D. Maximum Sum of Products
5 2 3 2 1 3 1 3 2 4 2
29
2 13 37 2 4
174
6 1 8 7 6 3 6 5 9 6 8 8 6
235
In the first example, you can reverse the subarray [4,5][4,5]. Then a=[2,3,2,3,1]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][3,5]. Then a=[1,8,3,6,7,6]a=[1,8,3,6,7,6] and 1⋅5+8⋅9+3⋅6+6⋅8+7⋅8+6⋅6=235.
这个题的意思就是给你两个数组a,b
你可以反转a的一个字串只能反转一次
问你得到的Σ(1,n)(ai*bi)最大
这个题是一个区间dp,
这可能是经验问题把,就是想到区间操作就应该想区间dp
dp[i][j]指的是反转区间i到j得到的值,然后再用前缀和维护一下就行
dp[i][j]=max(dp[i][j],dp[i+1][j-1]+a[i]*b[j]+a[j]*b[i]);
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int maxn=5e3+100; ll dp[maxn][maxn]; ll a[maxn]; ll b[maxn]; ll sum[maxn]; int 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]; } ll ans=0; for(int i=1;i<=n;i++){ dp[i][i]=a[i]*b[i]; sum[i]=sum[i-1]+dp[i][i]; } ans=sum[n]; for(int len=2;len<=n;len++){ for(int i=1;i+len-1<=n;i++){ int j=i+len-1; dp[i][j]=max(dp[i][j],dp[i+1][j-1]+a[i]*b[j]+a[j]*b[i]); ans=max(ans,sum[n]-(sum[j]-sum[i-1])+dp[i][j]); } } cout<<ans<<endl; }