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不能够.放牛仅仅能在有草地的. ...
随机推荐
- Pascal's Triangle II
1.题目描述 Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Re ...
- 委托demo
delegate bool Filter(string s); class test { static void Main() { Filter f=new Filter(A); Display(ne ...
- 使用 AppFuse 的七个理由
mvn -e archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfus ...
- golang中赋值string到array
要把一个string赋值给一个array,哥哥遇到一个纠结的困难,研究一番,发现主要原因是array和slice在golang里不是一个东西,本文提供两种解决方案. 在网络编程中network pac ...
- iOS Xcode的快捷键
将一些搜集和经常使用的快捷键记录下来,方便你我. Command +1~ 8: 跳转到导航区的不同位置 Command +0 :显示/隐藏导航区 Command Alt 1~ 6:在不同检测器之间跳转 ...
- mvc:annotation-driven' must have no character or element问题
使用SpringMVC,启动tomcat报这个错误 解决办法 首先将Spring版本提升到3.1及以上 如果还不行替换xml文件头部: <?xml version="1.0" ...
- CentOS 修改IP地址, DNS, 网关
一.CentOS 修改IP地址 修改对应网卡的IP地址的配置文件# vi /etc/sysconfig/network-scripts/ifcfg-eth0 修改以下内容DEVICE=eth0 #描述 ...
- javascript默认中文(汉字/标点)长度均为1的解决
javascript默认中文(汉字/标点)长度均为1 与后台(java)不一致, function calculate(str) { //var str="你好,哈哈哈000111lll&q ...
- 常用工具之stunnel
The stunnel program is designed to work as an SSL encryption wrapper between remote client and local ...
- I18N 国际编码
<%@ page language="java" import="java.util.*, cn.hncu.domain.*" pageEncoding= ...