【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;
}


posted @ 2014-11-02 22:33  kewowlo  阅读(136)  评论(0编辑  收藏  举报