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<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<cstdlib> #include<set> #include<queue> #include<stack> #include<vector> #include<map> #define N 100010 #define Mod 10000007 #define lson l,mid,idx<<1 #define rson mid+1,r,idx<<1|1 #define lc idx<<1 #define rc idx<<1|1 const double EPS = 1e-11; const double PI = acos ( -1.0 ); const double E = 2.718281828; typedef long long ll; const int INF = 1000010; using namespace std; int cnt[250], sum[250];///保存在一行中所有符合情况的值 int mp[110];//用来表示每行的情况,1代表不能安排士兵,0可以 int len, n, m; int dp[110][250][250]; bool ok ( int x ) { if ( x & ( x << 2 ) ) return false;///同一行距离为2的有没有冲突 return true; } int getsum ( int x )///没有冲突的时候计算1的个数 { int ans = 0; while ( x > 0 ) { if ( x & 1 )//最后一位是1 ans++; x >>= 1;///右移一位 } return ans; } void finds()///算出所有符合情况的值 { len = 0; memset ( cnt, 0, sizeof cnt ); for ( int i = 0; i < ( 1 << m ); i++ ) { if ( ok ( i ) ) { cnt[len] = i; sum[len++] = getsum ( i ); } } //cout << len << endl; } int main() { //freopen("in.txt","r",stdin); while ( cin >> n >> m ) { //m = 10; finds(); int c; memset ( mp, 0, sizeof ( mp ) ); for ( int i = 0; i < n; i++ ) { for ( int j = 0; j < m; j++ ) { scanf ( "%d", &c );///为了方便计算,吧、把1存为0,把0存为1 if ( !c ) mp[i] |= ( 1 << j ); } } memset ( dp, -1, sizeof ( dp ) ); for ( int i = 0; i < len; i++ )///先处理第一行 { if ( ! ( cnt[i]&mp[0] ) ) dp[0][i][0] = sum[i]; } for ( int i = 1; i < n; i++ ) { for ( int j = 0; j < len; j++ ) { if ( cnt[j]&mp[i] )///与mp[i]有冲突 continue; for ( int k = 0; k < len; k++ )///i-1行的情况 { if ( ( ( cnt[k] << 1 ) &cnt[j] ) || ( ( cnt[k] >> 1 ) &cnt[j] ) ) continue;///左右一个单位的对角上有人的情况 for ( int l = 0; l < len; l++ )///i-2行 { if ( cnt[j]&cnt[l] )///第i行与第2行有冲突 continue; if ( ( ( cnt[l] << 1 ) &cnt[k] ) || ( ( cnt[l] >> 1 ) &cnt[k] ) ) continue;///i-1行与i-2行 if ( dp[i - 1][k][l] == -1 ) continue; if ( dp[i - 1][k][l] + sum[j] > dp[i][j][k] ) dp[i][j][k] = dp[i - 1][k][l] + sum[j]; } } } } int ans = -1; for ( int i = 0; i < len; i++ ) for ( int j = 0; j < len; j++ ) if ( ans < dp[n - 1][i][j] ) ans = dp[n - 1][i][j]; cout << ans << endl; } return 0; }
原文:http://blog.csdn.net/acm_baihuzi/article/details/40866603