• AcWing 327 玉米田


    #include <bits/stdc++.h>
    
    using namespace std;
    const int MOD = 1e8;    //按1e8取模
    const int N = 14;       //M*N个小方格,上限都是12,这里我们故意取大一点,到14.
    const int M = 1 << 12;  //0~2^12-1,共2^12个状态
    int n, m;               //n行,m列
    int g[N];               //记录哪个位置是无法种田的,在题目中,输入的位置是0表示无法种田
    vector<int> st;         //哪些状态是本行合法的
    vector<int> head[M];    //某一个状态可以转化为哪些状态?
    int f[N][M];            //状态压缩的DP数组,一维:完成了第i行,二维:在状态是j(二进制状态)的情况下
    
    //状态检查是否合法,某个状态是不是存在连续1
    bool check(int s) {
        for (int i = 0; i < m; i++)//遍历每一列
            //判断连续1的位运算办法,好科学啊~
            if ((s >> i & 1) && (s >> (i + 1) & 1)) return false;
        return true;
    }
    
    int main() {
        //优化输入
        ios::sync_with_stdio(false);
        cin >> n >> m;
        //输入地图
        for (int i = 1; i <= n; i++)        //n行
            for (int j = 1; j <= m; j++) {  //共m列
                int t;
                cin >> t;
                //如果这个位置不能选,也按照状态压缩的思路,转为整数数值存入到g数组中
                //后面在计算第i行某一位是不是无法耕种时,也可以快速用&运算获得结果
                if (t == 0)g[i] += 1 << (j - 1);//这是一个值得学习的技巧
            }
    
        //预处理,哪些状态是合法状态
        for (int i = 0; i < 1 << m; i++)
            if (check(i)) st.push_back(i);
    
        //预处理,所有合法状态,可以转化为哪些合法状态
        for (int i = 0; i < st.size(); i++)
            for (int j = 0; j < st.size(); j++) {
                int a = st[i], b = st[j];
                //此步骤只处理两行之间不冲突就算合理转化,不考虑无法耕种情况
                if ((a & b) == 0) head[i].push_back(j);
            }
        //开始DP
        f[0][0] = 1;//啥也不放算一种方案
        for (int i = 1; i <= n + 1; i++) //遍历每一行
            for (int j = 0; j < st.size(); j++)//遍历每一个状态
                for (int k = 0; k < head[j].size(); k++) {//j状态的每一个可行转化
                    //如果此行的第j位无法耕种,那么不能转化
                    if (g[i] & st[j])continue;//这个&运算用的太漂亮了
                    //可以转化
                    f[i][j] += f[i - 1][head[j][k]];
                    //取模
                    f[i][j] = f[i][j] % MOD;
                }
        //最后一行取结果
        printf("%d", f[n + 1][0] % MOD);
        return 0;
    }
    
  • 相关阅读:
    国内乡村安防全面建设仍需推进,EasyNVR/EasyGBS/EasyCVR平台助力治安防控
    TSINGSEE青犀视频播放视频流的编码格式和封装格式有什么关系?
    全景摄像头怎么接入网页进行视频直播?
    EasyNTS编译报错could not read Username for XXXXX
    【LOJ#3005】Limited Memory
    【BZOJ2407】探险
    【洛谷P4480】餐巾计划问题
    【CF163E】e-Government
    【洛谷P4332】三叉神经树
    【洛谷P7518】宝石
  • 原文地址:https://www.cnblogs.com/littlehb/p/15755261.html
Copyright © 2020-2023  润新知