• poj 3254 Corn Fields 状态压缩,位运算集合操作


      状态  表示 前 i 行状态为 mask的 合法方案数量

      状态转移方程为

              

      其中 状态 j,k 满足条件   j & k = 0, j & ( j <<1) = 0, k & ( k <<1 ) = 0 ,且 J,K状态种植点合法

      

      因为两层间种植的点, 不可以上下相邻 所以有  J&K = 0

      因为同层间,种植点不可 两两相邻, 所以有 J & ( J << 1 ) = 0 , K & ( K << 1 ) = 0

      再而, 对于当前层, 某些点不可以 种植, 某些可以种植, 因为只有12位, 我们可以映射到一个 int 值使用位表示.

      定义状态 mask( i ) 表示 第 I 层的 M个位置 种植状态情况, 若 可种植为值为0, 不可种植为 1

      则 对于任意 行 状态 按位与上 该行种植情况:  mask ( i ) & J  = 0  则 表示当前合法, 无非法种植点

    解题代码

    View Code
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    typedef long long LL;
    const int mod = 1e8;
    
    LL dp[15][(1<<12)+10];
    int mp[15][15], d[15];
    int n, m, Max;
    
    bool legal( int k, int mask )
    {
        if( (mask & d[k]) > 0 ) return false;
        return true;
    }
    void print(int k)
    {
        for(int j = 0; j < Max; j++)
            printf("%4lld", dp[k][j]); puts("");
        
    }
    int main()
    {
        while( scanf("%d%d", &n,&m) != EOF)
        {
            
            memset( d,0,sizeof(d));    
            for(int i = 0; i < n; i++)
                for(int j = 0; j < m; j++)
                {    
                    scanf("%d",&mp[i][j]);
                    d[i] += ( mp[i][j] ? 0 : (1<<j) );    
                }    
            
            memset( dp, 0, sizeof(dp) );
            Max = (1<<m);
            for(int mask = 0; mask < Max; mask++)
                if( legal( 0, mask ) && ((mask &(mask<<1)) == 0)  )
                        dp[0][mask] = 1;
            
        //    print(0);
            for(int i = 1; i < n; i++)
            {
                for(int j = 0; j < Max; j++)
                {
                    for(int mask = 0; mask < Max; mask++)
                    {
                        if( legal(i,j) && legal(i-1,mask) )
                        {
                            if( ((j&mask)==0 ) && ((j&(j<<1))== 0) && ((mask&(mask<<1)) == 0) )    
                                dp[i][j] = (dp[i][j]+dp[i-1][mask])%mod;    
                        }
                    }
                }
            //    print(i);    
            }
            LL ans = 0;
            for(int mask = 0; mask < Max; mask++)
            {
                if( legal(n-1,mask ) && ((mask&(mask<<1)) == 0 ) )    
                    ans = (ans+dp[n-1][mask])%mod;    
            }
            printf("%lld\n", ans );    
        }
        return 0;
    }

      

  • 相关阅读:
    GET和POST区别
    es索引介绍
    前端 用法记录
    axios 使用
    react技巧 学习
    vuex 学习笔记
    fetch 学习笔记
    react-router 4.0 学习笔记
    react 学习笔记2
    react 学习笔记
  • 原文地址:https://www.cnblogs.com/yefeng1627/p/2860397.html
Copyright © 2020-2023  润新知