POJ 3254 Corn Fields(DP + 状态压缩)
题目链接: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 + 状态压缩)的更多相关文章
- poj - 3254 - Corn Fields (状态压缩)
poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...
- POJ 3254 Corn Fields(状态压缩)
一道状态压缩的题,错了好多次....应该先把满足的情况预处理出来 #include<iostream> #include<cstdio> #include<cstring ...
- POJ 3254 Corn Fields(状态压缩DP)
题目大意:给出一个M*N的矩阵,元素为0表示这个地方不能种玉米,为1表示这个地方能种玉米,现在规定所种的玉米不能相邻,即每行或者没列不能有相邻的玉米,问一共有多少种种植方法. 举个例子: 2 3 1 ...
- POJ 3254 Corn Fields [DP]
题意:略. 思路:第一次做状态压缩的dp. 在这里说一下状态压缩的原则.因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量 ...
- 状压DP POJ 3254 Corn Fields
题目传送门 /* 状态压缩DP:先处理硬性条件即不能种植的,然后处理左右不相邻的, 接着就是相邻两行查询所有可行的种数并累加 写错一个地方差错N久:) 详细解释:http://www.tuicool. ...
- poj3254 Corn Fields 利用状态压缩求方案数;
Corn Fields 2015-11-25 13:42:33 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10658 ...
- poj 3254 Corn Fields
http://poj.org/problem?id=3254 Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissio ...
- POJ 3254. Corn Fields 状态压缩DP (入门级)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9806 Accepted: 5185 Descr ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- POJ 3254 Corn Fields 状态压缩DP (C++/Java)
id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...
随机推荐
- c++面试常见160问
1.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"?答:首先,extern是C/C++语言中表明函数和全局变量作用范围的关键字,该关键字告诉编译器,其 ...
- 小波变换和motion信号处理(一)(转)
写的太好,不得不转:http://www.kunli.info/2011/02/15/fourier-wavelet-motion-signal-1/ 这是<小波变换和motion信号处理> ...
- 编译android版libmpg
环境:ubutnu 12.04,android SDK 1. 下载libmpg的一个android工程,得到一个Android-libmpg-master.zip.https://github.com ...
- cep
- 高效Linux用户需要了解的命令行技能
最近在Quora上看到一个问答题目,关于在高效率Linux用户节省时间Tips. 将该题目的回答进行学习总结,加上自己的一些经验,记录如下,方便自己和大家参考. 下面介绍的都是一些命令行工具,这些工具 ...
- 巧用MySQL之Explain进行数据库优化
前记:很多东西看似简单,那是因为你并未真正了解它. Explain命令用于查看执行效果.虽然这个命令只能搭配select类型语句使用,如果你想查看update,delete类型语句中的索引效果,也不是 ...
- Jquery常用方法篇(一)
1.add方法:将匹配的元素添加到当前的jquery对象集合中. 语法 add(expr,[context]) 参数1表示 用于匹配元素选择器(待添加的对象),或者用于动态生成的HTML代码(字符串) ...
- JS好的学习网站
1.JavaScript 秘密花园 2.W3CSchool 3.js严格模式 4.js核心之原型 5.尼古拉斯怎么面试前端工程师 6.zepto中文版api 7.jquery API
- MSSQLSERVER数据库- 杂记
查看语句执行时间: SET STATISTICS IO ONSET STATISTICS TIME ON SELECT * FROM dbo.NewsInfo Update的表关联例子: UPDATE ...
- [HTTP] HTTP Verb
HEAD: HEAD / HTTP/1.1 nc.exmaple.com HEAD is a interesting method, it allow you to get a header of f ...