hdu 5900 区间dp

来源:互联网 发布:me的域名 编辑:程序博客网 时间:2024/06/07 10:24

http://acm.hdu.edu.cn/showproblem.php?pid=5900

傻逼区间dp,一直wa,开了两个二维数组,一个记录i到j区间内是否可全部拿掉,一个标记i到j区间内拿掉可获得的最大价值

#include<bits/stdc++.h>using namespace std;int dp[306][306];long long v[306],k[306];long long sum[306][306];int main(){int T;int n,i,j;cin>>T;while(T--){memset(dp,0,sizeof(dp));memset(sum,0,sizeof(sum));cin>>n;for(i=1;i<=n;i++)cin>>k[i];for(i=1;i<=n;i++)cin>>v[i];for(i=1;i<n;i++)if(__gcd(k[i],k[i+1])!=1)dp[i][i+1]=1,sum[i][i+1]=v[i]+v[i+1];for(j=2;j<n;j++){for(i=1;i+j<=n;i++){int z=i+j;if(dp[i+1][z-1]&&(__gcd(k[i],k[z])!=1))sum[i][z]=sum[i+1][z-1]+v[i]+v[z],dp[i][z]=1;else{for(int kk=i;kk<z;kk++)sum[i][z]=max(sum[i][z],sum[i][kk]+sum[kk+1][z]),dp[i][z]|=(dp[i][kk]&&dp[kk+1][z]);}}}cout<<sum[1][n]<<endl;}} 
更优雅的做法是利用一个缀合

#include<bits/stdc++.h>using namespace std;long long v[306],k[306];long long sum[306][306];long long ss[306][306];int main(){int T;int n,i,j;cin>>T;while(T--){memset(sum,0,sizeof(sum));cin>>n;for(i=1;i<=n;i++)cin>>k[i];for(i=1;i<=n;i++)cin>>v[i];for(i=1;i<=n;i++){ss[i][i]=v[i];for(j=i+1;j<=n;j++){ss[i][j]=ss[i][j-1]+v[j];}}for(j=1;j<n;j++){for(i=1;i+j<=n;i++){int z=i+j;if(sum[i+1][z-1]==ss[i+1][z-1]&&(__gcd(k[i],k[z])!=1))sum[i][z]=ss[i][z];else{for(int kk=i;kk<z;kk++)sum[i][z]=max(sum[i][z],sum[i][kk]+sum[kk+1][z]);}}}cout<<sum[1][n]<<endl;}}



原创粉丝点击