题目链接:http://poj.org/problem?id=3254

题目大意:Farmer John 放牧cow,有些草地上的草是不能吃的,用0表示,然后规定两头牛不能相邻放牧。问你有多少种放牧方法。

Sample Input

2 3
1 1 1
0 1 0

Sample Output

9

分析:对于这种二维地图型,一般设状态dp[i][j]表示第 i 行第 j 状态达到要求的总数

  输入地图,用map[i]表示第 i 行中的状态。为了是sta[k]表示可行状态更加方便,map[i]中用0表示可放牧,1表示不可放牧,这样如果(sta[k]&map[i]==0)则说明满足放牧要求。

  动态规划:初始化:令dp[0][j]中可以在第一行放牧的状态j,dp[0][j]=1;

      转移方程:dp[i][j] = dp[i][j] + dp[i-1][k],k为所有满足条件的状态

代码如下:

 # include<stdio.h>
# include<string.h>
const int MAXN = <<;
const int MOD = ;
int sta[MAXN],num;
int dp[][MAXN]; //dp[i][j]表示第i行在集合j中满足条件的方案数
int map[]; //表示输入中每一行的状态
int n,m;
void init(){
num =;
int sum = <<m;
for(int i=; i<sum;i++) //从1到sum里边有满足该状态中放牛的位置不相邻的方案有num个
if(i&(i<<))
continue;
else
sta[num++] = i;
} void DP(){
int i,j,k;
for(i=; i<num; i++)
if(!(sta[i]&map[])) //寻找第一层满足条件的方案,令它为1
dp[][i] = ;
for(i=; i<n; i++)
for(j=; j<num; j++) //第i行是状态j
if(sta[j]&map[i]) //去掉与草场矛盾
continue;
else
for(k=; k<num; k++){ //第i-1行是状态k
if(map[i-]&sta[k]) //去掉与草场矛盾的
continue;
if(sta[k]&sta[j]) //去掉与上一行状态矛盾的
continue;
dp[i][j] = (dp[i][j] + dp[i-][k]) % MOD;
}
int ans = ;
for(i=; i<num; i++)
ans = (ans+dp[n-][i])%MOD;
printf("%d\n",ans);
}
int main(){
int i,j,temp;
while(scanf("%d%d",&n,&m)!=EOF){
memset(map,,sizeof(map));
for(i=; i<n; i++)
for(j=; j<m; j++){
scanf("%d",&temp);
if(temp==) //将每行状态二进制表示,1代表题目中的0,代表1
map[i] += <<(m-j-);
}
init();
DP();
}
return ;
}

 也可以使用滚动数组:

 # include<stdio.h>
# include<string.h>
const int MAXN = <<;
const int MOD = ;
int sta[MAXN],num;
int dp[][MAXN]; //dp[i][j]表示第i行在集合j中满足条件的方案数
int map[]; //表示输入中每一行的状态
int n,m;
void init(){
num =;
int sum = <<m;
for(int i=; i<sum;i++) //从1到sum里边有满足该状态中放牛的位置不相邻的方案有num个
if(i&(i<<))
continue;
else
sta[num++] = i;
} void DP(){
int i,j,k;
memset(dp,,sizeof(dp));
for(i=; i<num; i++)
if(!(sta[i]&map[])) //寻找第一层满足条件的方案,令它为1
dp[][i] = ;
for(i=; i<n; i++){
for(j=; j<num; j++) { //第i行是状态j
dp[i%][j] = ; //用来初始化,在滚动数组里边很重要
if(sta[j]&map[i]) //去掉与草场矛盾
continue;
else
for(k=; k<num; k++){ //第i-1行是状态k
if(map[i-]&sta[k]) //去掉与草场矛盾的
continue;
if(sta[k]&sta[j]) //去掉与上一行状态矛盾的
continue;
dp[i%][j] = (dp[i%][j] + dp[(i+)%][k]) % MOD;
}
}
}
int ans = ;
int temp = (n+)%;
for(i=; i<num; i++)
ans = (ans+dp[temp][i])%MOD;
printf("%d\n",ans);
}
int main(){
int i,j,temp;
while(scanf("%d%d",&n,&m)!=EOF){
memset(map,,sizeof(map));
for(i=; i<n; i++)
for(j=; j<m; j++){
scanf("%d",&temp);
if(temp==) //将每行状态二进制表示,1代表题目中的0,代表1
map[i] += <<(m-j-);
}
init();
DP();
}
return ;
}

POJ 3254 Corn Fields(DP + 状态压缩)的更多相关文章

  1. poj - 3254 - Corn Fields (状态压缩)

    poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...

  2. POJ 3254 Corn Fields(状态压缩)

    一道状态压缩的题,错了好多次....应该先把满足的情况预处理出来 #include<iostream> #include<cstdio> #include<cstring ...

  3. POJ 3254 Corn Fields(状态压缩DP)

    题目大意:给出一个M*N的矩阵,元素为0表示这个地方不能种玉米,为1表示这个地方能种玉米,现在规定所种的玉米不能相邻,即每行或者没列不能有相邻的玉米,问一共有多少种种植方法. 举个例子: 2 3 1 ...

  4. POJ 3254 Corn Fields [DP]

    题意:略. 思路:第一次做状态压缩的dp. 在这里说一下状态压缩的原则.因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量 ...

  5. 状压DP POJ 3254 Corn Fields

    题目传送门 /* 状态压缩DP:先处理硬性条件即不能种植的,然后处理左右不相邻的, 接着就是相邻两行查询所有可行的种数并累加 写错一个地方差错N久:) 详细解释:http://www.tuicool. ...

  6. poj3254 Corn Fields 利用状态压缩求方案数;

    Corn Fields 2015-11-25 13:42:33 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10658   ...

  7. poj 3254 Corn Fields

    http://poj.org/problem?id=3254 Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissio ...

  8. POJ 3254. Corn Fields 状态压缩DP (入门级)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Descr ...

  9. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  10. POJ 3254 Corn Fields 状态压缩DP (C++/Java)

    id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...

随机推荐

  1. SharePoint 2010 修改默认列表样式

    SharePoint 2010  修改默认列表样式 :可以通过修改 下面两个全局配置进行修改.(未完..更新中...)  C:\Program Files\Common Files\Microsoft ...

  2. 【Kafka入门】Kafka入门第一篇:基础概念篇

    Kafka简介 Kafka是一个消息系统服务框架,它以提交日志的形式存储消息,并且消息的存储是分布式的,为了提供并行性和容错保障,消息的存储是分区冗余形式存在的. Kafka的架构 Kafka中包含以 ...

  3. yum kvm

    ---恢复内容开始--- 1. 安装软件包:   yum -y install virt-manager; yum install qemu-kvm  yum install libvirt yum ...

  4. Windows Service中使用Threading.Timer需注意回收

    在Windows Service中使用Threading.Timer时需要注意回收池问题 Threading.Timer是基于线程池的,系统会对其进行垃圾回收. 当Threading.Timer定义在 ...

  5. 整理收藏一份PHP高级工程师的笔试题

    整理了一份PHP高级工程师的笔试题,问题很全面.嗯,基本上这些题都答得不错,那么你应该可以胜任大部分互联网企业的PHP职位了.下面直接上题. 1. 基本知识点 HTTP协议中几个状态码的含义:503, ...

  6. Duff and Weight Lifting - 587A

    题目大意:某个人训练举重,他每次可以举起来2^wi的重量,不过这个人比较懒所以他想尽量减少训练的次数,如果所有的训练重量2^a1 +2^a2+....2^ak = 2^x,那么这些重量可以一次性训练( ...

  7. poj 1144 Network【双连通分量求割点总数】

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11042   Accepted: 5100 Descript ...

  8. LIVE555研究之三:LIVE555基础

    LIVE555基础 LIVE555是为流媒体提供解决方式的跨平台C++开源项目.从今天起我们将正式開始深入LIVE555代码. 一.各库简要介绍 LIVE555下包括LiveMedia.UsageEn ...

  9. Yii CGridView 基本使用(三)关联表相关字段搜索

    加入 关联表 相关字段的搜索: 先说一句,我们在这里仅仅谈 "一对多" 的关联搜索,首先,不要忘了我们的数据库,忘记的同学请戳这里:这里.能够看到在 tbl_post 中是有一个外 ...

  10. android91 代码注册广播接收者

    Activity: package com.itheima.register; import android.os.Bundle; import android.app.Activity; impor ...