您的位置:首页 > 其它

状态压缩棋盘问题2道 sgu131&poj1038

2013-04-25 18:02 459 查看
SGU 131

dp[i][s],表示第i行状态为s的时的数量,这个时候按照题意扩展可行的上一行状态t,则dp[i][s]=sum{dp[i-1][u-t]},其中u为(2^m)-1...状态转移略麻烦,一次性写不对的话,debug真心受不鸟了。。。。附代码:

#include <iostream>
#include <cstdio>

#define N 11
#define M 520
#define u (1<<m)-1
#define t (1<<k)
#define ll __int64

using namespace std;

ll dp
[M];
int m;

void search(int i,int k,int p,int q)
{
    if (k==m)
    {
        if (i==1) dp[1][p]=1;
        else dp[i][p]+=dp[i-1][u-q];
        return;
    }
    search(i,k+1,p,q);
    if (k+2<=m) search(i,k+2,p+3*t,q);
    if (i==1) return;
    if (!(q&t)) search(i,k+1,p+t,q+t);
    if (!(q&t)&&k+2<=m) search(i,k+1,p+t,q+3*t);
    if (!(q&t)&&k+2<=m) search(i,k+2,p+3*t,q+t);
    if (k+2<=m) search(i,k+2,p+3*t,q+2*t);
    if (k>0&&!(q&t)&&!(q&(t>>1))) search(i,k+1,p+t,q+t/2*3);
}

int main()                                    
{
    int n,i,j;
    while (cin>>n>>m)
    {
      //  memset(dp,0,sizeof(dp));
        for (i=1;i<=n;i++) search(i,0,0,0);
        cout<<dp
[u]<<endl;    
    }
    return 0;
}


POJ 1038

这个写的好搓,读者可以考虑三进制的状态压缩。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

#define u (1<<m)-1
#define cl(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a)
#define M 1028
#define N 155

using namespace std;

int a
,dp[2][M][M],f[2][M],m,res;

void running(int e,int p,int q,int value)
{
    int i,v,w,x;
    x=e%2;
    for (i=q;i<=u;i++)
        if (!(i&a[e-1])&&((i&q)==q))
        {
            v=i-q;
            if (dp[x][q][i]>=f[1-x][v]+value) continue;
            for (w=v;w<=u;w++)
                if (!(p&w)&&!(w&a[e-2])&&((w&v)==v))
                {
                    dp[x][q][i]=max(dp[x][q][i],dp[1-x][v][w]+value);
                    res=max(res,dp[x][q][i]);
                }
            f[x][q]=max(f[x][q],dp[x][q][i]);
        }
}

void search(int e,int i,int p,int q,int k)
{
    int p1,q1,j; 
    if (i==m)
    {
        if (e==2) 
        {
            dp[0][q][q]=k;
            f[0][q]=k;
            res=max(res,k);
        }
        else running(e,p,q,k);
        return;
    }
    search(e,i+1,p,q,k);
    if (i+3<=m)
    {
        p1=p;
        q1=q+(1<<i)*7;
        if (!(q1&a[e])&&!(q1&a[e-1])) search(e,i+3,p1,q1,k+1);
    }
    if (e!=2&&i+2<=m)
    {
        p1=p+(1<<i)*3;
        q1=q+(1<<i)*3;
        if (!(p1&a[e-2])&&!(q1&a[e])&&!(q1&a[e-1])) search(e,i+2,p1,q1,k+1);
    }
}

int main()
{
    int T,i,j,k,n;
    ss(T);
    while (T--)
    {
        ss(n);ss(m);ss(k);
        cl(a);
        for (i=1;i<=k;i++)
        {
            int x,y;
            ss(x);ss(y);
            a[x]+=(1<<(y-1));    
        }
        cl(dp);cl(f);
        res=0;
        for (i=2;i<=n;i++) search(i,0,0,0,0);    
        printf("%d\n",res);
    }
    return 0;   
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: