状态压缩学习论文:TJU 周伟的《状态压缩》
http://wenku.baidu.com/view/070924ec102de2bd96058839.html
http://poj.org/problem?id=1185第一个状态压缩DP,
留代码以后好看:
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #define N 101 5 #define M 11 6 #define S 66 7 #define MAX(a,b) a>b?a:b 8 9 int state[N][S]; 10 char map[M]; 11 int dp[2][S][S]; 12 int count[N][S]; 13 int gra; 14 int n,m,s; 15 int dfs(int i){ 16 int total = 1<<m; 17 int item; 18 int k,j; 19 for (k= 1,j=0;j<total;j++){ 20 if ((j&gra)==0 && ((j>>2)&j)==0 && ((j>>1)&j)==0){ 21 state[i][k]=j; 22 item = j; 23 while (item){ 24 if (item%2) 25 count[i][k]++; 26 item>>=1; 27 } 28 k++; 29 } 30 31 } 32 count[i][0]=k; 33 return 0; 34 } 35 36 37 int main() 38 { 39 int max; 40 41 while (~scanf("%d%d",&n,&m)){ 42 memset(state,0,sizeof(state)); 43 //state[i][j] 表示第i行的放置方案为j 44 //count[i][0]表示第i行可以放置的方案数 45 //count[i][j] 表示第i行放置j时,j的二进制表示有多少个1 46 memset(count,0,sizeof(count)); 47 memset(dp,0,sizeof(dp)); 48 for (int i=0;i<n;i++){ 49 scanf("%s",map); 50 for (int j = gra=0;j<m;j++){ 51 gra=gra*2+(map[j]=='P'?0:1); 52 } 53 //gra 表示当前行P的状态 54 55 dfs(i); 56 //搜索当前行的可能放置的状态state 57 } 58 59 //初始化第一行 60 for (int i=1;i<count[0][0];i++){ 61 for (int j=1;j<S;j++){ 62 dp[0][i][j]=count[0][i]; 63 } 64 } 65 //初始化第二行 66 for (int i=1;i<count[1][0];i++){ 67 for (int j=1;j<count[0][0];j++){ 68 if ((state[0][j] & state[1][i])==0) 69 dp[1][i][j]=count[0][j]+count[1][i]; 70 } 71 } 72 73 74 75 if (n>2){ 76 for (int i=2;i<n;i++){ 77 for (int j=1;j<count[i][0];j++){ 78 for (int k=1;k<count[i-1][0];k++){ 79 max = 0; 80 if ((state[i][j] &state[i-1][k])==0){ 81 for (int l = 1;l<count[i-2][0];l++){ 82 if((state[i][j]&state[i-2][l])==0 && (state[i-1][k]&state[i-2][l])==0){ 83 max = MAX(dp[(i-1)&1][k][l]+count[i][j],max); 84 } 85 } 86 } 87 dp[i&1][j][k] = max; 88 } 89 } 90 } 91 } 92 max= 0; 93 for (int i=1;i<count[n-1][0];i++){ 94 for (int j=1;j<S;j++){ 95 max = MAX(max,dp[(n-1)&1][i][j]); 96 } 97 } 98 printf("%d\n",max); 99 } 100 return 0; 101 }