D. Maximum Sum of Products
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 ∑i=1nai⋅bi is maximized.
Input
The first line contains one integer n (1≤n≤5000).
The second line contains n integers a1,a2,…,an (1≤ai≤107).
The third line contains n integers b1,b2,…,bn (1≤bi≤107).
Output
Print single integer — maximum possible sum after reversing at most one subarray (continuous subsegment) of a.
Examples
input 1
5
2 3 2 1 3
1 3 2 4 2
output 1
29
input 2
2
13 37
2 4
output 2
174
input 3
6
1 8 7 6 3 6
5 9 6 8 8 6
output 3
235
Note
In the first example, you can reverse the subarray [4,5]. Then a=[2,3,2,3,1] and 2⋅1+3⋅3+2⋅2+3⋅4+1⋅2=29.
In the second example, you don’t need to use the reverse operation. 13⋅2+37⋅4=174.
In the third example, you can reverse the subarray [3,5]. Then a=[1,8,3,6,7,6] and 1⋅5+8⋅9+3⋅6+6⋅8+7⋅8+6⋅6=235.
基本思路:
找到交换长度之间的关系,并计算出交换此等长度后的累加和.。
通项公式为:
dp内存储反转子集的累加和
dp[反转子集长度] = a[反转子集头顶点] * b[反转子集尾顶点] + dp[交换子集长度-2] + a[反转子集尾顶点] * b[反转子集头顶点];
反转此子集后的合集累加和 = dp[反转子集长度] + 累加和[反转子集头顶点-1] + 累加和[集合尾节点] - 累加和[反转子集尾顶点]
PS:代码能不看就不要看,写属于是基本思路的微变形,有属于个人习惯的预处理,不怎么好理解。但是如果是完全不会的话就看自己的学习习惯了。
Code
#include<iostream>
#define ll long long
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
int main()
{
ll n, i, j, sum, t;
cin >> n;
ll a[n + 1], b[n + 1], c[n + 2] = {0}, dp[n + 1][n + 1] = {0};
for ( i = 1; i <= n; i++ ) cin >> a[i];
for ( i = 1; i <= n; i++ )
{
cin >> b[i];
dp[0][i] = dp[0][i + 1] = dp[0][i + 2] = 0;
dp[1][i] = a[i] * b[i];
c[i] = c[i - 1] + a[i] * b[i];
}
for ( i = 1, sum = c[n]; i < n; i++ )
{
for ( j = 1; j <= n - i; j++ )
{
t = c[j - 1] + c[n] - c[j + i];
dp[i + 1][j] = a[j] * b[j + i] + a[j + i] * b[j] + dp[i - 1][j + 1];
sum = sum < dp[i + 1][j] + t ? dp[i + 1][j] + t : sum;
}
}
cout << sum << endl;
return 0;
}