给你两个长度为n的数组a和数组b。
你可以反转数组a的一段连续区间。
问操作后 a1 * b1 + a2 * b2+…+ an * bn的最大值为多少。
Input
第一行给出整数n,1<=n<=5000,
第二行包含n个整数表示ai,1<=ai<=10^7。
第三行包含n个整数表示bi,1<=bi<=10^7。
Output
打印一行整数表示反转一段数组a的区间后最大可以得到的和。
Examples
Input
5 2 3 2 1 3 1 3 2 4 2
Output
29
Input
2 13 37 2 4
Output
174
Input
6 1 8 7 6 3 6 5 9 6 8 8 6
Output
235
区间dp
二维数组dp记录区间 i~j 的反转后相乘的区间和,一维数组 f[i] 记录没反转的情况下 1~i的区间相乘和,然后区间dp模板。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e3+4;
ll a[N],b[N],dp[N][N],f[N];
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int i,j,k;
int n,m,t;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
cin>>b[i];
dp[i][i]=a[i]*b[i];
f[i]=f[i-1]+a[i]*b[i];
}
ll mx=f[n];
for(int l=2;l<=n;l++)
{
for(int i=1;i+l-1<=n;i++)
{
int j=i+l-1;
dp[i][j]=dp[i+1][j-1]+a[i]*b[j]+a[j]*b[i];
mx=max(mx,dp[i][j]+f[i-1]+f[n]-f[j]);
}
}
cout<<mx;
return 0;
}