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

    n * m 个玉米

    n*m个数字 0 或者1

    1可以种玉米 0 不能  种玉米不能相邻

    计算有几种 种的方法

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    
    using namespace std;
    #define MAXN 13
    #define MAXN1 10000
    #define mod 100000000
    int n,m;
    int z[MAXN][MAXN];
    int num[MAXN1];
    int cnt;
    int dp[MAXN][MAXN1];  //dp[i][j]   第一维是行 第二维是列 表示这一行这个状态的数目  
    int x[MAXN]; //用来记录每一行的二进制数   1
    
    void solve()                // 0&1 =0   就1&1=1
    {
        for(int i=0;i<(1<<m);i++)   //所有可能的状态  就是这一行不可能相邻  10010  100100  这样可以  11010  110100  不行  
            if((i&(i<<1))==0)
                num[cnt++]=i;
    }
    bool jug(int state,int r)  //这个状态 和这一行是否矛盾
    {
        if(!(state&(~x[r])))   
            return 1;
        return 0;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
                for(int i=1;i<=n;i++)
                    for(int j=1;j<=m;j++)
                        scanf("%d",&z[i][j]);
                cnt=0;
                solve();
                memset(dp,0,sizeof(dp));
                memset(x,0,sizeof(x));
                for(int i=1;i<=n;i++)
                {
                    for(int j=1;j<=m;j++)
                        if(z[i][j])
                            x[i]+=(1<<(m-j));
                }
                dp[0][0]=1;
                for(int i=1;i<=n;i++)
                {
                    for(int st=0;st<cnt;st++)
                    {
                        if(jug(num[st],i)) //这一行 和 这个状态
                        {
                            for(int pa=0;pa<cnt;pa++)
                            {
                                if(jug(num[pa],i-1)&&!(num[st]&num[pa]))//前一行和前一个状态 这和状态和前一个状态
                                    dp[i][num[st]]+=dp[i-1][num[pa]];
                            }
                        }
    
                    }
                }
                int ans=0;
                for(int i=0;i<cnt;i++)        //所有的数目要加一下
                    ans=(ans+dp[n][num[i]])%mod;
                printf("%d
    ",ans);
        }
    
        return 0;
    }
  • 相关阅读:
    判断大小写数字个数,取交集和并集
    软件工程总结
    正则表达式(邮箱)
    今天距离你生日的天数
    字符数量,查回文
    解决一个表单中的两个或者多个按钮提交到不同的页面中问题
    jsp前台输入框不输入值,后台怎么取出整型?
    第十次作业
    CMD命令行
    Kali渗透安卓手机
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6127339.html
Copyright © 2011-2022 走看看