• poj 3254 Corn Fields


      状态DP

      二进制题型,用0和1来确定所有的情况。

      把每一行安排的情况看成一个二进制数,如果这一行的某一列安排了一头奶牛,那么对应的二进制就是1,如果没有安排那么就是0.如果某个状态表示里出现了两个连续的1,那么这个状态永远是非法的,可以去掉,这样处理之后剩下的可能合法。

      令dp[i][j]表示第i行状态为j时有多少可能的安排方法,那么状态转移方程是:如果j是合法状态:dp[i][j]=sum{dp[i-1][k]},其中满足k&j==0。

      

    #include<stdio.h>
    #include<string.h>
    #define maxn (1<<13)
    #define mod 100000000
    
    int n,m;
    int dp[15][maxn];
    bool flag[15][maxn];
    int mat[15];
    int mm;
    void init()
    {
        for(int i=1;i<=n;i++)
        for(int j=0;j<=mm;j++)
        {
            flag[i][j]=true;
            if((~mat[i]&j)||(j&(j<<1)))
            flag[i][j]=false;
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(dp,0,sizeof(dp));
            memset(mat,0,sizeof(mat));
            int num;
            for(int i=1;i<=n;i++)
            for(int j=m-1;j>=0;j--)
            {
                scanf("%d",&num);
                if(num==1)mat[i]|=(1<<j);
            }
            mm=(1<<m)-1;
            init();
            for(int i=0;i<=mm;i++)
            if(flag[n][i]) dp[n][i]=1;
            int i,j;
            for(i=n-1;i>=1;i--)
            {
                for(j=0;j<=mm;j++)
                {
                   if(!flag[i][j]) continue;
                   for(int k=0;k<=mm;k++)
                   {
                       if(!flag[i+1][k]) continue;
                       if(!(j&k))
                       dp[i][j]+=dp[i+1][k];
                   }
                   dp[i][j]%=mod;
                }
            }
            int ans=0;
            for(i=0;i<=mm;i++)
            ans+=dp[1][i]%mod;
            ans%=mod;
            printf("%d
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    安装jar包到本地仓库和远程仓库
    服务之间的资源权限校验
    函数指针
    malloc分配内存
    cuda_vs_报错无法解析的外部错误
    c语言读写文件
    C++使用using namespace std报错分析与解决方案
    MPI环境配置
    c语言学习
    openMP
  • 原文地址:https://www.cnblogs.com/yongren1zu/p/3264361.html
Copyright © 2020-2023  润新知