hdu 4539(状态压缩dp)
题意:曼哈顿距离是指:|x1-x2|+|y1-y2|,只要知道这个概念题意就懂了。
分析:这道题与前面做的几道题有所不同,因为当前行不仅与前一行有关,而且与前两行有关,所以我们开数组的时候还要记录前两行的状态,所以我们需要开设三维数组。
代码实现:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,a[105]; int dp[2][202][202],st[202],num,b[202]; int suan(int x) { int sum=0,i; for(i=1; i<=10; i++) { if((x&1)) sum++; x=x>>1; } return sum; } void chushihua() { int i,max=1<<10; for(i=0; i<max; i++) if((i&(i<<2))==0&&(i&(i>>2))==0) { st[num]=i; b[num++]=suan(i); } } void solve() { int i,j,k,l,p=1,max=1<<m,res=0,temp; memset(dp,0,sizeof(dp)); if(n>=1) for(i=0; i<num&&st[i]<max; i++) { if((a[1]&st[i])!=st[i]) continue; temp=b[i]; dp[1][0][i]=temp; } if(n>1) { p=p^1; for(i=0; i<num&&st[i]<max; i++) { if((a[2]&st[i])!=st[i]) continue; temp=b[i]; for(j=0; j<num&&st[j]<max; j++) { if((a[1]&st[j])!=st[j]) continue; if((st[i]&(st[j]<<1))!=0||(st[i]&(st[j]>>1))!=0) continue; if(dp[0][j][i]<dp[1][0][j]+temp) dp[0][j][i]=dp[1][0][j]+temp; } } for(i=3; i<=n; i++) { p=p^1; for(j=0; j<num&&st[j]<max; j++) { if((a[i]&st[j])!=st[j]) continue; temp=b[j]; for(k=0; k<num&&st[k]<max; k++) { if((st[j]&(st[k]<<1))!=0||(st[j]&(st[k]>>1))!=0) continue; if((a[i-1]&st[k])!=st[k]) continue; for(l=0; l<num&&st[l]<max; l++) { if((a[i-2]&st[l])!=st[l]) continue; if((st[k]&(st[l]<<1))!=0||(st[k]&(st[l]>>1))!=0) continue; if((st[l]&st[j])!=0) continue; if(dp[p][k][j]<dp[1-p][l][k]+temp) dp[p][k][j]=dp[1-p][l][k]+temp; } } } } } for(i=0; i<num&&st[i]<max; i++) for(j=0; j<num&&st[j]<max; j++) { temp=dp[p][i][j]; if(temp>res) res=temp; } printf("%d\n",res); } int main() { int i,j,temp; num=0; memset(b,0,sizeof(b)); chushihua(); while(scanf("%d%d",&n,&m)!=EOF) { memset(a,0,sizeof(a)); for(i=1; i<=n; i++) { a[i]=0; for(j=1; j<=m; j++) { scanf("%d",&temp); a[i]=(a[i]<<1)+temp; } } solve(); } return 0; }
posted on 2013-11-29 19:58 后端bug开发工程师 阅读(288) 评论(0) 编辑 收藏 举报