HDU 4539 郑厂长系列故事——排兵布阵 <<状压dp
Posted computer-luo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4539 郑厂长系列故事——排兵布阵 <<状压dp相关的知识,希望对你有一定的参考价值。
思路
被这道题折磨死了,只是发上来纪念一下,思路同方格取数(1),我已经疯了!
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int maze[110][15]; 4 int n,m; 5 vector<int> all[110]; 6 int dp[110][200][200]; 7 int num[1<<10]; 8 bool check(int r,int state) 9 { 10 for(int i=m-1;i>=0;i--) 11 { 12 if(state&1) 13 { 14 if(maze[r][i]==0) return false; 15 if(i<1) continue; 16 if((state>>2)&1) return false; 17 } 18 state>>=1; 19 } 20 return true; 21 } 22 bool ok(int pre,int now,int f) 23 { 24 if(f==1) 25 { 26 if((pre>>1)&now||pre&(now>>1)) return false; 27 return true; 28 } 29 else{ 30 if(!(pre&now)) return true; 31 return false; 32 } 33 } 34 void db() 35 { 36 int cnt=0; 37 for(int i=0;i<n;i++) 38 { 39 all[i].clear(); 40 for(int state=0;state<1<<m;state++) 41 { 42 if(check(i,state)) 43 { 44 //cout<<i<<":"<<bitset<3>(state)<<endl; 45 cnt++,all[i].push_back(state); 46 num[state]=__builtin_popcount(state); 47 } 48 } 49 } 50 //cout<<cnt<<endl; 51 } 52 int main() 53 { 54 //freopen("data.in","r",stdin); 55 //freopen("data.out","w",stdout); 56 while(~scanf("%d%d",&n,&m)) 57 { 58 memset(maze,0,sizeof(maze)); 59 for(int i=0;i<n;i++) 60 { 61 for(int j=0;j<m;j++) 62 { 63 scanf("%d",&maze[i][j]); 64 } 65 } 66 db(); 67 memset(dp,0,sizeof(dp)); 68 int ans=0; 69 if(n==1) 70 { 71 for(int i=0;i<all[0].size();i++) 72 { 73 ans=max(ans,num[all[0][i]]); 74 } 75 goto ending; 76 } 77 for(int i=0;i<all[0].size();i++) 78 { 79 for(int j=0;j<all[1].size();j++) 80 { 81 int now=all[1][j],pre=all[0][i]; 82 if(ok(pre,now,1)) 83 { 84 dp[1][j][i]=max(num[all[1][j]]+num[all[0][i]],dp[1][j][i]); 85 //cout<<dp[1][j][i]<<endl; 86 ans=max(ans,dp[1][j][i]); 87 } 88 } 89 } 90 for(int i=2;i<n;i++) 91 { 92 for(int j=0;j<all[i].size();j++) 93 { 94 for(int k=0;k<all[i-1].size();k++) 95 { 96 int pre=all[i-1][k],now=all[i][j]; 97 if(!ok(pre,now,1)) continue; 98 else{ 99 for(int l=0;l<all[i-2].size();l++) 100 { 101 int pp=all[i-2][l]; 102 if(ok(pp,now,2)&&ok(pp,pre,1)) 103 { 104 dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+num[all[i][j]]); 105 ans=max(ans,dp[i][j][k]); 106 } 107 } 108 } 109 } 110 } 111 } 112 ending: 113 printf("%d ",ans); 114 } 115 }
以上是关于HDU 4539 郑厂长系列故事——排兵布阵 <<状压dp的主要内容,如果未能解决你的问题,请参考以下文章