【DP】 HDU 4539 郑厂长系列故事——排兵布阵 状压
纯暴力无任何优化
3500+ms
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #define cler(arr, val) memset(arr, val, sizeof(arr)) typedef long long LL; const int MAXN = 100200; const int MAXM = 6000010; const int INF = 0x3f3f3f3f; const int mod = 1000000007; int mp[104][15],dp[2][(1<<10)+3][(1<<10)+3]; int t,m,n; bool pd(int x,int j)//判断符合不符合原图 { if(j<=0) j=0; for(int i=1; i<=m; i++) { if((1<<(i-1))&x) { if(mp[j][i]!=1) return true; } } for(int i=1; i<=m-2; i++) { if(((1<<(i-1))&x)&&((1<<(i+1))&x)) return true; } return false; } bool ok(int x,int y)//判 { for(int i=1; i<=m; i++) { if((1<<(i-1))&x) { if((1<<(i)&y)) return false; if(i>=2&&(1<<(i-2)&y)) return false; } } return true; } bool pdd(int x,int y) { for(int i=0; i<m; i++) { if(((1<<i)&x)&&((1<<i)&y)) return false; } return true; } int pre[33]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif while(cin>>n>>m) { cler(dp,0); cler(mp,0); cler(pre,0); for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) scanf("%d",&mp[i][j]); int f=1; for(int i=1; i<=n; i++) { for(int j=0; j<(1<<m); j++) //该行 { if(pd(j,i)) continue;//判断符合不符合原图 int num=0; for(int l=0; l<m; l++) //计算个数 if((1<<l)&j) num++; for(int k=0; k<(1<<m); k++) //上一行 { if(pd(k,i-1)) continue;//判断符合不符合原图 if(ok(j,k))//判断这两行可不可行 { for(int p=0; p<(1<<m); p++)//上两行 { if(pd(p,i-2)) continue; if(ok(k,p)&&pdd(j,p)) { dp[f][j][k]=max(dp[f][j][k],dp[f^1][k][p]+num); } } } } } f^=1; } int ans=0; for(int i=0; i<(1<<m); i++) for(int j=0; j<(1<<m); j++) ans=max(ans,dp[f^1][i][j]); cout<<ans<<endl; } return 0; }