题目链接:https://vjudge.net/contest/224636#problem/G

转载于:https://blog.csdn.net/harrypoirot/article/details/23163485

题目大意:

农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的(用1标记),农夫可以在这些格子里放牛,其他格子则不能放牛(用0标记),并且要求不可以使相邻格子都有牛。现在输入数据给出这块地的大小及可否放牧的情况,求该农夫有多少种放牧方案可以选择(注意:任何格子都不放也是一种选择,不要忘记考虑!

解题分析就看上面那篇博客,我也是照着上面学的。

#include <cstdio>
#include <cstring>
using namespace std;#define mod 100000000
int M, N, top = 0;
//top表示每行最多的状态数int state[600];
//state存放每行所有的可行状态(即没有相邻的状态)int dp[20][600];
//dp[i][j]:对于前i行数据,第i行有前j种可能状态时的解
int cur[20];
//cur[i]表示的是第i行整行的情况

inline bool ok(int x) {    //判断状态x是否可行if (x&x << 1)    return false;//若存在相邻两个格子都为1,则该状态不可行return true;
}void init() {            //遍历所有可能的状态top = 0;int total = 1 << N; //遍历状态的上界for (int i = 0; i < total; ++i) {      //总共有total种状态需要讨论if (ok(i))state[++top] = i;       //state[]为一行中所有可行的状态
    }
}//原理就是,如果你在不能够放1的位置放了1,那么这个方案肯定不可行
inline bool fit(int x, int k) { //判断状态x 与第k行的实际状态的逆是否有‘重合’               //判断理论上每一行能符合的情况是否与某一特定的行符合,因为每一行规定了能放1的位置if (x&cur[k])return false; //若有重合,(即x不符合要求)return true;  //若没有,则可行
}int main() {while (scanf("%d%d", &M, &N) != EOF) {init();memset(dp, 0, sizeof(dp));for (int i = 1; i <= M; ++i) {cur[i] = 0;int num;for (int j = 1; j <= N; ++j) {  //输入时就要按位来存储,cur[i]表示的是第i行整行的情况,每次改变该数字的二进制表示的一位scanf("%d", &num);  //表示第i行第j列的情况(0或1)if (num == 0) //若该格为0    cur[i] += (1 << (N - j)); //则将该位置为1(注意要以相反方式存储,即1表示不可放牧}       //cur[]数组,利用状态压缩,用一维数组,表示了二维的数据
        }for (int i = 1; i <= top; i++) {if (fit(state[i], 1)) {  //判断所有可能状态与第一行的实际状态的逆是否有重合dp[1][i] = 1;  //若第1行的状态与第i种可行状态吻合,则dp[1][i]记为1
            }}      //先算出第一行的情况,初始化dp[1][]的所有情况,方便下面dp的递推,//前面的都是准备工作,都是为了下面的这个状态转移方程做准备for (int i = 2; i <= M; ++i) {  //i索引第2行到第M行for (int k = 1; k <= top; ++k) { //该循环针对所有可能的状态,找出一组与第i行相符的state[k]if (!fit(state[k], i))continue; //判断是否符合第i行实际情况for (int j = 1; j <= top; ++j) { //找到state[k]后,再找一组与第i-1行符合,且与第i行(state[])不冲突的状态state[j]if (!fit(state[j], i - 1))continue;  //判断是否符合第i-1行实际情况          //找出上一行的所有可行状态if (state[k] & state[j])continue;    //判断是否与第i行冲突                 //判断第i行的状态是否与上一行冲突dp[i][k] = (dp[i][k] + dp[i - 1][j]) % mod;  //若以上皆可通过,则将'j'累加到‘k'上              }    //这里就相当于dp[i][k]+=dp[i-1][j],只不过因为要取模运算,所以写成这样}        //状态转移方程的根据为,dp[i][k]表示第i行采用方案k时,前i总共有多少种可行的情况
        }int ans = 0;for (int i = 1; i <= top; ++i) { //累加最后一行所有可能状态的值,即得最终结果!!!ans = (ans + dp[M][i]) % mod;                       }printf("%d\n", ans);}
}

2018-07-26

转载于:https://www.cnblogs.com/00isok/p/9370993.html

Poj - 3254 Corn Fields (状压DP)(入门)相关推荐

  1. POJ - 3254 Corn Fields(状压dp)

    题目链接:点击查看 题目大意:给出一个n*m的地图,有些位置不能放牧,然后放牧的条件是相邻两个格子不允许同时使用,问可行方案有几种 题目分析:因为给出的数据范围很小,并且放牧的状态是放或者不放,很容易 ...

  2. poj - 3254 Corn Fields (状态压缩dp入门)

    http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...

  3. poj3254 Corn Fields 状压DP入门

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19368   Accepted: 10169 Des ...

  4. [USACO06NOV]玉米田Corn Fields (状压$dp$)

    题目链接 Solution 状压 \(dp\) . \(f[i][j][k]\) 代表前 \(i\) 列中 , 已经安置 \(j\) 块草皮,且最后一位状态为 \(k\) . 同时多记录一个每一列中的 ...

  5. poj 3254 Corn Fields 状态压缩dp

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K       Description Farmer John has purchased a ...

  6. poj 3254 Corn Fields (状态压缩DP)

    题目:http://poj.org/problem?id=3254 思路见代码: #include<iostream> using namespace std;const int MOD= ...

  7. POJ - 1185 炮兵阵地(状压dp)

    题目链接:点击查看 题目大意:中文题,题意很清晰,不多赘述 题目分析:最基础的状压dp,需要考虑如何转移,因为每一个炸弹所涉及的范围都是上下左右两个格子,我们可以从第一行开始向下转移,这样某一行的状态 ...

  8. 状态压缩dp入门 第一题 POJ 3254 Corn Fields

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6460   Accepted: 3436 Descr ...

  9. poj3254(状压dp入门第一道题,很详细)

    题目链接:http://poj.org/problem?id=3254 学习博客:https://blog.csdn.net/harrypoirot/article/details/23163485 ...

最新文章

  1. 洛谷2051 [AHOI2009]中国象棋
  2. 京东面试题:二叉树直径
  3. Hosting in .NET Core
  4. 阿里P8架构师谈:Web前端、应用服务器、数据库SQL等性能优化总结
  5. 完成css的切图 图片任意,css切图是什么意思
  6. 特征筛选8——递归特征删除(REF)筛选特征(有监督筛选)
  7. 【Linux】第一章 整合 JDK 和 MariaDB(附 Linux 基本命令)
  8. RHEL 8 - 记录用户会话操作
  9. 【干货】推荐系统的商业价值:如何量化?怎么提升?
  10. 学习指南_这可能是全网最详细的HTTP学习指南了
  11. Android已读未读功能,Android实现小圆点显示未读功能
  12. 疑惑光栅投影中条纹间距和频率的关系
  13. 浅谈学习的深度和广度
  14. 用k-mer分析进行基因组调查:(五)用GCE分步实现
  15. 【知识点和练习题】心田花开:二年级语文汉语拼音补习
  16. cf Gym 101086M ACPC Headquarters : AASTMT (Stairway to Heaven)
  17. 微信小程序+PHP 从零写一个微信小程序
  18. 亚马逊云科技连续12年蝉联Gartner云基础设施和平台服务魔力象限领导者
  19. 基于mjpg-streamer实现树莓派推流至上位机(自用)
  20. 游戏专辑一 3D游戏碰撞之体素内存、效率优化(未完待续10/14)

热门文章

  1. BASIC-11 十六进制转十进制
  2. 【Tools】Visual Studio 2010下载和安装
  3. 【嵌入式】C语言高级编程-地址对齐(07)
  4. 【Linux】一步一步学Linux——rename命令(36)
  5. 【计算机类】大学生计算机专业电子书汇总
  6. [Qt教程] 第39篇 网络(九)进程和线程
  7. 联机装箱问题 java_Java实现 洛谷 P1049 装箱问题
  8. android studio 反编译修改versioncode,在android studio 中修改versioncode 跟versionname(示例代码)...
  9. loop指令 c语言,arm汇编loop指令
  10. 推箱子java下载_Java实现简单推箱子游戏