ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Educational Codeforces Round 108 (Rated for Div. 2) D. Maximum Sum of Products

2021-05-04 02:04:22  阅读:200  来源: 互联网

标签:Educational Rated int Sum 枚举 区间 include LL 翻转


一、算法分析

给定两个序列 a和 b ,将 a中的一个子序列翻转后 ( 也可以不翻转 ) ,使得 a,b 对应项乘积和最大。当时首先想到的是类似区间DP的东西,然后不知道怎么回事脑子晕了觉得枚举能做,枚举确实能做,但是又把数据范围搞错了,误以为要开高精度才行,然后搞了半天没时间了。

首先是枚举做法,这应该是比较经典的字符串枚举算法了。容易想到朴素的方法是枚举两个端点,将之间的部分进行翻转,但是这样复杂度过高。其实每次可以枚举翻转区间的中间点,然后很容易可以向两边扩展。设翻转区间的端点为u和v,则每次区间扩展对于扩展前区间的影响是a[v]*b[u]+a[u]*b[v]-a[u]*b[u]-a[v]*b[v].对于由于翻转区间的长度可能是奇数或者偶数,因此需要分两种情况。当然也可以通过中间补0的方式使之变成一种情况。

DP的做法大同小异,仍然是扩展区间,但是用了区间DP的思路。

二、代码

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #define LL long long
 6 using namespace std;
 7 const int N=5050<<1;
 8 LL a[N],b[N];
 9 LL s;
10 int n;
11 int main(){
12     
13     cin>>n;
14     for(int i=1;i<=n*2;i+=2) cin>>a[i];                              //n乘2因为中间要补0
15     for(int i=1;i<=n*2;i+=2) cin>>b[i];
16     for(int i=1;i<=n*2;i++) s+=a[i]*b[i];
17     LL maxx=0;
18     for(int i=1;i<=n*2;i++){
19         LL p=0;
20         for(int l=i,r=i;l>=1 && r<=n*2;l--,r++){
21             p+=(a[r]*b[l]+a[l]*b[r]-a[l]*b[l]-a[r]*b[r]);
22             maxx=max(maxx,p);
23         }
24     }
25     
26     cout<<s+maxx;
27     
28     return 0;
29     
30     
31 }
 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #define LL long long
 6 using namespace std;
 7 const int N=5050;
 8 LL a[N],b[N];
 9 LL s;
10 int n;
11 LL f[N][N];
12 int main(){
13     
14     cin>>n;
15     for(int i=1;i<=n;i++) cin>>a[i];
16     for(int j=1;j<=n;j++) cin>>b[j];
17     for(int i=1;i<=n;i++) s+=a[i]*b[i];
18     
19     for(int i=1;i<=n;i++) f[i][i]=s;
20     for(int len=2;len<=n;len++)
21         for(int l=1;l+len-1<=n;l++){
22             int r=l+len-1;
23             if(len==2) f[l][r]=f[l][l]-a[l]*b[l]-a[r]*b[r]+a[l]*b[r]+a[r]*b[l];   //注意特殊处理一下len==2的情况
24             else f[l][r]=f[l+1][r-1]-a[l]*b[l]-a[r]*b[r]+a[l]*b[r]+a[r]*b[l];
25         }
26     LL res=0;
27     for(int i=1;i<=n;i++)
28         for(int j=i;j<=n;j++) res=max(res,f[i][j]);
29     
30     cout<<res;
31     
32     return 0;
33     
34     
35 }

 

标签:Educational,Rated,int,Sum,枚举,区间,include,LL,翻转
来源: https://www.cnblogs.com/talk-sea/p/14728669.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有