首页 > 代码库 > Hdu 5900 QSC and Master
Hdu 5900 QSC and Master
给出n对数keyi,vali表示当前这对数的键值和权值,可以操作将连续的两个数合并,如果满足gcd(a[i],a[i+1])>1,得到
的价值是两个数的权值和,每次合并两个数之后,这两个数就会消失,然后旁边的数会接上
比如1 2 3 4 合并了 2 3 则 剩下1 4也可以合并.
处理出任意区间内的所有数是否可以合并
对于当前的[l,r]区间,如果区间[l+1,r-1]可以合并,且gcd(a[l]+a[r])>1的话,则整个区间[l,r]可以合并,价值也就是前缀和
同理处理出其他的情况 [l,r-2] [l+1,r]
区间dp,对于当前的l,r区间,如果可以合并,则直接加上区间和
反之,则枚举一个中间值k,找出区间内最大满足情况的值
所以是2次dp
#include <bits/stdc++.h>typedef long long LL;using namespace std;int n;LL sum[1000],a[1000],b[1000];LL g[302][302],dp[302][302];LL gcd(LL a,LL b){ return b==0?a:gcd(b,a%b);}int main(){ int T; scanf("%d",&T); while(T--){ memset(a,0,sizeof a); memset(b,0,sizeof b); memset(sum,0,sizeof sum); memset(g,0,sizeof g); memset(dp,0,sizeof dp); scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); for(int i=1;i<=n;i++) scanf("%I64d",&b[i]),sum[i]=sum[i-1]+b[i]; for(int i=1;i<=n-1;i++) if(gcd(a[i],a[i+1])>1) g[i][i+1]=1; for(int len=2;len<=n;len+=2){ for(int j=1;j+len-1<=n;j++){ int l=j,r=j+len-1; if(gcd(a[l],a[r])>1 && g[l+1][r-1]) g[l][r]=1; if(gcd(a[l],a[l+1])>1 && g[l+2][r]) g[l][r]=1; if(gcd(a[r-1],a[r])>1 && g[l][r-2]) g[l][r]=1; } } for(int len=2;len<=n;len++) for(int j=1;j+len-1<=n;j++){ int l=j,r=j+len-1; if(g[l][r]) dp[l][r]=sum[r]-sum[l-1]; else for(int k=l;k<r;k++) dp[l][r]=max(dp[l][r],dp[l][k]+dp[k+1][r]); } printf("%I64d\n",dp[1][n]); } return 0;}
Hdu 5900 QSC and Master
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。