hdu 1565 方格取数(1) 状态压缩dp
2015-10-15 14:17
363 查看
做了很久的一道题。
做dp题要先写出子问题。
做dp题要先写出子问题。
做dp题要先写出子问题。
dp[i][j]代表到第i行第j种情况,能取得的最大的数。
所以dp[i][j]=max(dp[i-1][k]+sum,dp[i][j]);
这里k&j!=1。sum为改行的值。
定义一个dp[20][1<<20]的数组mle,可以定义一个dp【2】【1<<20】的滚动数组。
不过这份代码耗时比较大,应该是有可以优化的地方。
优化后的代码
做dp题要先写出子问题。
做dp题要先写出子问题。
做dp题要先写出子问题。
dp[i][j]代表到第i行第j种情况,能取得的最大的数。
所以dp[i][j]=max(dp[i-1][k]+sum,dp[i][j]);
这里k&j!=1。sum为改行的值。
定义一个dp[20][1<<20]的数组mle,可以定义一个dp【2】【1<<20】的滚动数组。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int dp[2][1<<20]; int s[20000]; int n; int map[25][25]; int k=0; void solve(int x,int y) { if(x>=n-1) return ; int p=y&1; for(int i=1;i<k;i++) { if(s[i]>=(1<<n)) break; for(int j=1;j<k;j++) { if(s[j]>=(1<<n)) break; if(s[j]&s[i]) continue; int sum=0; for(int kk=0;kk<n;kk++) { if(s[j]&(1<<kk)) sum+=map[y][kk]; } dp[p][s[j]]=max(sum+dp[1-p][s[i]],dp[p][s[j]]); } } solve(x+1,y+1); return ; } int main() { for(int i=0;i<(1<<20);i++) if(!(i&(i<<1))) s[k++]=i; while(cin>>n) { memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&map[i][j]); int end=1<<n; for(int i=1;i<k;i++) { int sum=0; if(s[i]>=end) break; for(int j=0;j<n;j++) { if(s[i]&(1<<j)) sum+=map[0][j]; } dp[0][s[i]]=sum; } solve(0,1); int maxv=0; for(int i=1;i<end;i++) { int d=(n-1)&1; maxv=max(dp[d][i],maxv); } cout<<maxv<<endl; } return 0; }
不过这份代码耗时比较大,应该是有可以优化的地方。
优化后的代码
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int dp[2][1<<20]; int s[20000]; int n; int map[25][25]; int main() { int lon=0; for(int i=0;i<(1<<20);i++) if(!(i&(i<<1))) s[lon++]=i; while(~scanf("%d",&n)) { for(int i=0;i<n;i++) for(int j=0;j<n;j++) scanf("%d",&map[i][j]); memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++) { int p=i&1; for(int k=1;k<lon;k++) { if(s[k]>=(1<<n)) break; int sum=0; for(int j=0;j<n;j++) if(s[k]&(1<<j)) sum+=map[i][j]; int maxv=0; for(int j=1;j<lon;j++) { if(s[j]>=(1<<n)) break; if(s[j]&s[k]) continue; maxv=max(dp[1-p][s[j]],maxv); /*cout<<maxv<<endl;*/ } dp[p][s[k]]=maxv+sum; } } int maxn=0; int d=(n-1)&1; for(int i=0;i<lon;i++) if(s[i]<(1<<n)) maxn=max(maxn,dp[d][s[i]]); cout<<maxn<<endl; } return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow
- zoj3605 Find the Marble(三维dp)
- Word Break I,II, Triangle,Palindrome Partitioning 动态规划 DP