zoukankan      html  css  js  c++  java
  • poj 2411 状态压缩dp

    思路:将每一行看做一个二进制位,那么所有的合法状态为相邻为1的个数一定要为偶数个。这样就可以先把所有的合法状态找到。由于没一层的合法状态都是一样的,那么可以用一个数组保存。由第i-1行到第i行的状态转移是dp[i][now|num[j]]+=dp[i-1][k],其中now为(1<<m)-1-k;也就是把k中含有0的变1,1边0。k为第i-1行的所有二进制状态,转移条件是k&num[j]==num[j]。唯一注意的是,最后一行的条件是k^num[j]==0.

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define Maxn 13
    #define inf 0x7fffffff
    using namespace std;
    __int64 dp[Maxn][1<<Maxn];
    int num[1<<Maxn],cnt1,cnt2,graphic[Maxn],co,n,m;
    void dfs(int j,int f)
    {
        int i;
        if(j==m)
        {
            int sum=0;
            if(f)
                graphic[j]=1;
            else
                graphic[j]=0;
            for(i=m;i>=1;i--)
                sum+=graphic[i]*(1<<(m-i));
            num[++cnt2]=sum;
            return ;
        }
        if(!f)
        {
            graphic[j]=0;
            dfs(j+1,0);
            graphic[j]=1;
            dfs(j+1,1);
        }
        else
        {
            graphic[j]=1;
            dfs(j+1,0);
        }
    }
    int main()
    {
        int i,j,k;
        while(scanf("%d%d",&n,&m)!=EOF,n||m)
        {
            if((n*m)%2)
            {
                printf("0
    ");
                continue;
            }
            if(n==1)
            {
                printf("1
    ");
                continue;
            }
            memset(dp,0,sizeof(dp));
            graphic[0]=0;
            cnt2=0;
            dfs(1,0);
            for(i=1;i<=cnt2;i++)
                dp[1][num[i]]=1;
            int temp=1<<m;
            temp--;
            for(i=2;i<=n-1;i++)
            {
                for(j=1;j<=cnt2;j++)
                {
                    for(k=0;k<=temp;k++)
                    {
                        if((k&num[j])==num[j])
                        {
                            int now=temp-k;
                            dp[i][now|num[j]]+=dp[i-1][k];
                        }
                    }
                }
            }
            __int64 ans=0;
            for(j=1;j<=cnt2;j++)
            {
                for(k=0;k<=temp;k++)
                {
                    if((k^num[j])==0)
                        ans+=dp[i-1][k];
                }
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    COGS727 [网络流24题] 太空飞行计划
    Bzoj1692 洛谷P2870 [Usaco2007 Dec]队列变换
    Bzoj1029 [JSOI2007]建筑抢修
    Bzoj3168 [Heoi2013]钙铁锌硒维生素
    Bzoj4566 [Haoi2016]找相同字符
    Bzoj4771 七彩树
    Bzoj2597 [Wc2007]剪刀石头布
    Bzoj4773 负环
    HDU5772 String problem
    Bzoj1324 Exca王者之剑
  • 原文地址:https://www.cnblogs.com/wangfang20/p/3240466.html
Copyright © 2011-2022 走看看