6 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2比较简单的状态压缩#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int map[105][15]; int dp[1<<10][1<<10],tem[1<<10][1<<10]; int now[1<<10],pre[1<<10],prepre[1<<10],ans[1<<10]; int l_now,l_pre,l_prepre; int n,m; void dfs(int id,int k,int p,int sum) { if(k>=m) { now[++l_now] = p; ans[l_now] = sum; return; } if(k>=2 && map[id][k] && !(p&(1<<(k-2))))//这格可以放,而左边第二格不能放,那么在这个位置放下 dfs(id,k+1,p|(1<<k),sum+1); else if(k<2 && map[id][k])//如果是前两列,这格可以放就先放下 dfs(id,k+1,p|(1<<k),sum+1); dfs(id,k+1,p,sum);//这格不放 } void solve() { int i,j,k,t; tem[1][1] = pre[1] = prepre[1] = 0; l_now = l_pre = l_prepre = 1; for(k = 0; k<n; k++) { l_now = 0; dfs(k,0,0,0); for(i = 1; i<=l_now; i++) for(j = 1; j<=l_pre; j++) dp[i][j] = 0; for(i = 1; i<=l_now; i++) { for(j = 1; j<=l_pre; j++) { for(t = 1; t<=l_prepre; t++) { if(now[i] & prepre[t]) continue; if(now[i] & (pre[j]>>1)) continue; if(now[i] & (pre[j]<<1)) continue; dp[i][j] = max(dp[i][j],tem[j][t]+ans[i]); } } } for(i = 1; i<=l_now; i++) for(j = 1; j<=l_pre; j++) tem[i][j] = dp[i][j]; for(i = 1; i<=l_pre; i++) prepre[i] = pre[i]; for(i = 1; i<=l_now; i++) pre[i] = now[i]; l_prepre = l_pre; l_pre = l_now; } } int main() { int i,j; while(~scanf("%d%d",&n,&m)) { for(i = 0; i<n; i++) for(j = 0; j<m; j++) scanf("%d",&map[i][j]); solve(); int maxn = 0; for(i = 1; i<=l_pre; i++) for(j = 1; j<=l_prepre; j++) maxn = max(maxn,tem[i][j]); printf("%d\n",maxn); } return 0; }
原文地址:http://blog.csdn.net/libin56842/article/details/24742491