D. Maximum Sum of Products ###K //K

题目链接:https://codeforces.ml/problemset/problem/1519/D

 

思路: 可以预处理前后缀和 然后枚举翻转的终点 然后左右同时扫一遍得到答案

为了让长度为偶数的情况好处理 可以像manacher那样 把长度边为2*n 中间用0隔开

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e4+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define pi pair<int,int>
 7 #define fi first
 8 #define sc second
 9 #define pb push_back
10 
11 
12 
13 ll pre[maxn],suf[maxn];
14 ll a[maxn],b[maxn];
15 int n;
16 
17 
18 int main()
19 {
20     ios::sync_with_stdio(0);
21     cin.tie(0);
22     cin>>n;
23     for(int i=1;i<=n*2;i+=2) cin>>a[i];
24     for(int i=1;i<=n*2;i+=2) cin>>b[i];
25     for(int i=1;i<=n*2;i++)
26     {
27         pre[i]=pre[i-1]+a[i]*b[i];
28     }
29     for(int i=n*2;i>=1;i--)
30     {
31         suf[i]=suf[i+1]+a[i]*b[i];
32     }
33     ll ans=pre[n*2];
34     for(int i=1;i<=n*2;i++)
35     {
36         ll sum=a[i]*b[i];
37         for(int j=1;j<=n;j++)
38         {
39             int l=i-j,r=i+j;
40             if(l<=0||r>=n*2) break;
41             sum+=a[l]*b[r]+a[r]*b[l];
42             ans=max(ans,sum+suf[r+1]+pre[l-1]);
43         }
44 
45     }
46 
47     cout<<ans<<'\n';
48 
49 
50 
51 }
View Code

 

也可以用像区间dp求最长回文串一样  f[i][j] 为翻转i j 能得到的额外贡献

每次更新状态 只需要让 a[i]*b[j]+a[j]*b[i] 与 a[i]*b[i]+b[j]*b[j] 作差即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=5e3+10;
 4 const int mod=1e9+7;
 5 #define ll long long
 6 #define ull unsigned long long
 7 #define pi pair<int,int>
 8 #define fi first
 9 #define sc second
10 #define pb push_back
11 
12 
13 ll a[maxn],b[maxn],f[maxn][maxn];
14 
15 int main()
16 {
17     ios::sync_with_stdio(false);
18     cin.tie(0);
19     int n;cin>>n;
20     for(int i=1;i<=n;i++) cin>>a[i];
21     for(int i=1;i<=n;i++) cin>>b[i];
22     ll sum=0,ans=0;
23     for(int i=1;i<=n;i++) sum+=a[i]*b[i];
24 
25     for(int len=2;len<=n;len++)
26     {
27         for(int i=1;i+len-1<=n;i++)
28         {
29             int j=i+len-1;
30             ll t=a[i]*b[i]+a[j]*b[j];
31             ll tt=a[i]*b[j]+a[j]*b[i];
32             f[i][j]=f[i+1][j-1]+tt-t;
33             ans=max(ans,f[i][j]);
34         }
35     }
36     cout<<sum+ans<<'\n';
37 
38 
39 
40 
41 
42 }
View Code

 

posted @ 2021-04-30 09:33  canwinfor  阅读(109)  评论(0编辑  收藏  举报