标签:hdu4539 郑厂长系列故事排兵布阵 状态压缩 dp
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;
}
标签:hdu4539 郑厂长系列故事排兵布阵 状态压缩 dp
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/40866603