Maximum Sum of Products
题面翻译
给定两个长为 $n$ 的序列 $a$ 和 $b$。你可以对 $a$ 的一段区间翻转,也可以不翻转,要求翻转后 $a$ 与 $b$ 对应位置之积的和最大。即求下式的值最大:
$$\sum_{i=1}^na_i\times b_i$$
其中 $n\le 5000$,$a_i,b_i\le10^7$。
translated by @zc_Ethan
题目描述
You are given two integer arrays $ a $ and $ b $ of length $ n $ .
You can reverse at most one subarray (continuous subsegment) of the array $ a $ .
Your task is to reverse such a subarray that the sum $ \sum\limits_{i=1}^n a_i \cdot b_i $ is maximized.
输入格式
The first line contains one integer $ n $ ( $ 1 \le n \le 5000 $ ).
The second line contains $ n $ integers $ a_1, a_2, \dots, a_n $ ( $ 1 \le a_i \le 10^7 $ ).
The third line contains $ n $ integers $ b_1, b_2, \dots, b_n $ ( $ 1 \le b_i \le 10^7 $ ).
输出格式
Print single integer — maximum possible sum after reversing at most one subarray (continuous subsegment) of $ a $ .
样例 #1
样例输入 #1
5
2 3 2 1 3
1 3 2 4 2
样例输出 #1
29
样例 #2
样例输入 #2
2
13 37
2 4
样例输出 #2
174
样例 #3
样例输入 #3
6
1 8 7 6 3 6
5 9 6 8 8 6
样例输出 #3
235
提示
In the first example, you can reverse the subarray $ [4, 5] $ . Then $ a = [2, 3, 2, 3, 1] $ and $ 2 \cdot 1 + 3 \cdot 3 + 2 \cdot 2 + 3 \cdot 4 + 1 \cdot 2 = 29 $ .
In the second example, you don’t need to use the reverse operation. $ 13 \cdot 2 + 37 \cdot 4 = 174 $ .
In the third example, you can reverse the subarray $ [3, 5] $ . Then $ a = [1, 8, 3, 6, 7, 6] $ and $ 1 \cdot 5 + 8 \cdot 9 + 3 \cdot 6 + 6 \cdot 8 + 7 \cdot 8 + 6 \cdot 6 = 235 $ .
题目范围小,考虑暴力,可以枚举每一个区间,要发现如果交换ai和aj,那么对答案的贡献就是(ajbi+aibj)-(aibi+ajbj)即(ai-aj)*(bj-bi),所以应该枚举每一个点当作区间中点,左右两边扩张区间,找到最大的增量区间,但是区间中点不一定有对称的与中间的值,所以l=i,r=i和l=i,r=i+1都要试一遍
const int N = 1e6 + 10;
int a[N];
int b[N];
void solve()
{
int n; cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
int mmax = 0;
for (int i = 1; i <= n; i++) mmax += a[i] * b[i];
int jia = 0;
for (int i = 1; i <= n; i++)
{
int l = i, r = i;
int ans = 0;
while (l >= 1 && r <= n)
{
ans += (a[l] - a[r]) * (b[r] - b[l]);
jia = max(jia, ans);
l--, r++;
}
}
for (int i = 1; i <= n - 1; i++)
{
int l = i, r = i+1;
int ans = 0;
while (l >= 1 && r <= n)
{
ans += (a[l] - a[r]) * (b[r] - b[l]);
jia = max(jia, ans);
l--, r++;
}
}
cout << mmax+jia << '\n';
}