D. Maximum Sum of Products
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
题目大意:
给两个数组a,b,可以翻转一次a中的一个子数组,求两数组对应数的积之和最大值。
思路:
看n最大才5000,所以可以暴力一点O(n*n)。枚举每一种交换的情况,取最大就行了。
代码:
#include<algorithm>
#include<iostream>
#include<cmath>
#define endl '\n'
#define int long long
using namespace std;
const int N=5050;
int a[N];
int b[N];
signed main()
{
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 sum=0;
for(int i=1;i<=n;++i)
{
sum+=a[i]*b[i];//不交换时积之和
}
int ans=sum;
for(int i=1;i<=n;++i)//中间相差奇数个数
{
int res=sum;
int j=1,l=i-j,r=i+j;
for(;j<=n&&l>=1&&r<=n;)
{
res-=a[l]*b[l]+a[r]*b[r];//容斥
res+=a[l]*b[r]+a[r]*b[l];
ans=max(ans,res);
++j;
l=i-j,r=i+j;
}
}
for(int i=1;i<n;++i)//中间相差偶数个数
{
int res=sum;
int j=1,l=i-j+1,r=i+j;
for(;j<=n&&l>=1&&r<=n;)
{
res-=a[l]*b[l]+a[r]*b[r];
res+=a[l]*b[r]+a[r]*b[l];
ans=max(ans,res);
++j;
l=i-j+1,r=i+j;
}
}
cout<<ans<<endl;
return 0;
}
具体的双指针部分不是很好实现