D. Maximum Sum of Products(区间dp)

D. Maximum Sum of Products

 

 

Examples
input
Copy
5
2 3 2 1 3
1 3 2 4 2
output
Copy
29
input
Copy
2
13 37
2 4
output
Copy
174
input
Copy
6
1 8 7 6 3 6
5 9 6 8 8 6
output
Copy
235
Note

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 21+33+22+34+12=29.

In the second example, you don't need to use the reverse operation. 132+374=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 15+89+36+68+78+66=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; 
}

 

 

 

posted @ 2021-05-06 19:59  lipu123  阅读(150)  评论(0)    收藏  举报