zoukankan      html  css  js  c++  java
  • POJ3254 Corn Fields(状态压缩DP)

    题目链接

    分析:

    作为状态压缩DP入门题,很好。

    由题意可知:

    1.任意两牛(包括行和列)不能临近

    2.牛只能在有草的即值为1的地方

    3.不放牛也为一种方案

    定义dp[i][s]为第i行状态s下的方案数。

    dp[i][s] = ∑(dp[i-1][s']),其中s'为不与s冲突的状态

    注意:

    因为位运算优先级很低,所以要多加括号。因此

    if((cow & (cow<<1)) != 0) return 0;
    和
    if(cow & (cow<<1) != 0) return 0;
    是不一样的
    #include <cstdio>
    #include <cstring>
    
    #define MAXN 13
    #define MODNUM 100000000
    
    int n, m;
    int filter[MAXN];
    int dp[MAXN][1<<MAXN];
    
    int check(int cow, int grass){
        if((cow & grass) != cow) return 0;  //检测牛是否都在有草的地方,如果否返回0
        if((cow & (cow<<1))) return 0;  //该行是否有两牛相邻,有就返回0
        return 1;
    }
    
    void solve(){
        int i, j, itype, k, ans;
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        itype = (1<<m);
        for(i=1; i<=n; i++){
            for(j=0; j<itype; j++){
                if(check(j, filter[i])){
                    for(k=0; k<itype; k++){
                        if((j&k) == 0){ //保证对于该行j状态与上一行k状态,两行间没有临近的牛
                            dp[i][j] = (dp[i][j] + dp[i-1][k]) % MODNUM;
                        }
                    }
                }
            }
        }
        ans = 0;
        for(i=0; i<itype; i++){
            ans = (ans+dp[n][i]) % MODNUM;
        }
        printf("%d\n", ans);
    }
    
    int main(){
        int i, j, t;
    
        scanf("%d %d", &n, &m);
    
        for(i=1; i<=n; i++){
            filter[i] = 0;
            for(j=0; j<m; j++){
                scanf("%d", &t);
                filter[i] = (filter[i]<<1)+t;   //将每行草地用二进制表示
            }
        }
    
        solve();
    
        return 0;
    }
  • 相关阅读:
    1、MyBatis 快速入门
    1、Spring Framework入门
    1、基本数据类型
    2020软件工程个人作业06
    谭山明月有秋水--事后诸葛亮
    谭山明月有秋水——项冲刺第七天
    谭山明月有秋水——冲刺第六天
    谭山明月有秋水——冲刺第一天
    谭山明月有秋水——冲刺第二天
    谭山明月有秋水——冲刺第三天
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3014334.html
Copyright © 2011-2022 走看看