• POJ 3254 Corn Fields (状态压缩DP)


    题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案)。

    分析:方格边长范围只有12,用状态压缩dp好解决。

    预处理:每一行的障碍用一个状态保存好     每一行不考虑障碍的所有符合要求的状态保存好     第一行的方案数记录好。

    然后一行一行递推,每一行只与上一行有关。


    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <set>
    #include <queue>
    #include <stack>
    #include <climits>//形如INT_MAX一类的
    #define MAX 100005
    #define INF 0x7FFFFFFF
    #define mod 100000000
    //#pragma comment(linker, "/STACK:36777216") ///传说中的外挂
    using namespace std;
    
    int map[15][15];
    int dp[15][1 << 12];
    int buff[1 << 12]; //保存每一行不考虑障碍的状态
    int bar[15]; //保存每一行的障碍的状态
    int n,m,sum,ans;
    
    void getbuff() {
        int total = 1 << m;
        for(int i=0; i<total; i++) {
            if(i & (i >> 1)) continue;
            buff[sum++] = i;
        }
    }
    
    void solve() {
        for(int i=1; i<n; i++) {
            for(int j=0; j<sum; j++) {
                if(buff[j] & bar[i]) continue;
                for(int k=0; k<sum; k++) {
                    if(buff[j] & buff[k]) continue;
                    if(buff[k] & bar[i-1]) continue; //注意也要判冲突与否
                    dp[i][buff[j]] = (dp[i][buff[j]] + dp[i-1][buff[k]]) % mod;
                }
            }
        }
        ans = 0;
        for(int j=0; j<sum; j++) {
            ans = (ans + dp[n-1][buff[j]]) % mod;
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof(dp));
        memset(bar,0,sizeof(bar));
        sum = 0;
        for(int i=0; i<n; i++) {
            for(int j=0; j<m; j++) {
                scanf("%d",&map[i][j]);
                if(map[i][j] == 0) {
                    int move = m - j - 1;
                    bar[i] += 1 << move;
                }
            }
        }
        getbuff();
        for(int j=0; j<sum; j++) {
            if(buff[j] & bar[0]) continue; // 注意
            dp[0][buff[j]] = 1;
        }
        solve();
        printf("%d
    ",ans);
        return 0;
    }


  • 相关阅读:
    OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位
    How To Move Or Rebuild A Lob Partition
    Hadoop入门进阶步步高(三)-配置Hadoop
    [学习笔记]整体DP
    leetcode404
    leetcode349
    leetcode383
    leetcode453
    leetcode455
    leetcode167
  • 原文地址:https://www.cnblogs.com/pangblog/p/3265260.html
Copyright © 2020-2023  润新知