http://poj.org/problem?id=3254

题意:有一个n*m的农场(01矩阵),其中1表示种了草可以放牛,0表示没种草不能放牛,并且如果某个地方放了牛,它的上下左右四个方向都不能放其他的牛,

问总共有多少种放牛方案??(不放也是一种方案)

状态压缩讲的好的博客

分析:利用状态压缩进行求解,先筛选出每行所有的可能状态,然后将每行与所有可行状态进行比较。

dp[i][j]表示当第i行的状态为j时前i行的放牛方案总数。

所以状态转移方程便是 dp[i][j] = dp[i][j]+dp[i-1][t] //t代表第i-1行所有符合条件的状态数。

最后的结果为 sum(dp[n][i]) ..数组开小了,不停WA

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 12
#define mod 100000000
using namespace std;
int dp[N+][<<N]; ///dp[i][j]表示当第i行的状态为j时前i行的放牛方案总数
int state[<<N]; ///保存所有的合法状态数
int cur[N+]; ///每一行的状态,注意这里保存的是0,因为当我们保存0时,如果某一状态与当前行相与不为0,那么
///就能判断出那个状态是不合法的(假设那个位置不应该种草,而它种了草)
int n,m;
bool check(int k){
if(k&(k<<)) return false;
return true;
}
void init(int &k){
for(int i=;i<(<<m);i++){
if(check(i)) state[++k]=i;
}
//printf("%d\n",k);
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF){
int k = ;
init(k);
int num;
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++){
cur[i]=;
for(int j=;j<=m;j++){
scanf("%d",&num);
if(num==) cur[i]+=(<<(j-));
}
}
for(int i=;i<=k;i++){
if(!(cur[]&state[i])){
dp[][i]=;
}
}
for(int i=;i<=n;i++){
for(int j=;j<=k;j++){
if(cur[i]&state[j]) continue; ///枚举第i行的可行状态state[j]
for(int t = ;t<=k;t++){
if(cur[i-]&state[t]) continue; ///枚举第i-1行的可行状态state[t]
if(state[j]&state[t]) continue; ///判断相邻两行状态是否合法
dp[i][j] = (dp[i][j]+dp[i-][t]+mod)%mod;
}
}
}
int ans = ;
for(int i=;i<=k;i++){
ans = (ans+dp[n][i]+mod)%mod;
}
printf("%d\n",ans);
}
return ;
}

poj 3254(状态压缩+动态规划)的更多相关文章

  1. poj 3254 状态压缩DP

    思路:把每行的数当做是一个二进制串,0不变,1变或不变,找出所有的合法二进制形式表示的整数,即相邻不同为1,那么第i-1行与第i行的状态转移方程为dp[i][j]+=dp[i-1][k]: 这个方程得 ...

  2. poj 3254 状态压缩

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15285   Accepted: 8033 Desc ...

  3. POJ 3254 状态压缩 DP

    B - Corn Fields Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:65536KB    ...

  4. BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划

    BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...

  5. 状态压缩动态规划 状压DP

    总述 状态压缩动态规划,就是我们俗称的状压DP,是利用计算机二进制的性质来描述状态的一种DP方式 很多棋盘问题都运用到了状压,同时,状压也很经常和BFS及DP连用,例题里会给出介绍 有了状态,DP就比 ...

  6. 【学术篇】状态压缩动态规划——POJ3254/洛谷1879 玉米田Corn Field

    我要开状压dp的坑了..直播从入门到放弃系列.. 那就先拿一道状压dp的水题练练手吧.. 然后就找到了这一道..这道题使我清醒地认识到阻碍我的不是算法,而是视力= = 传送门: poj:http:// ...

  7. 状态压缩动态规划(状压DP)详解

    0 引子 不要999,也不要888,只要288,只要288,状压DP带回家.你买不了上当,买不了欺骗.它可以当搜索,也可以卡常数,还可以装B,方式多样,随心搭配,自由多变,一定符合你的口味! 在计算机 ...

  8. POJ 1185 状态压缩DP(转)

    1. 为何状态压缩: 棋盘规模为n*m,且m≤10,如果用一个int表示一行上棋子的状态,足以表示m≤10所要求的范围.故想到用int s[num].至于开多大的数组,可以自己用DFS搜索试试看:也可 ...

  9. 状态压缩动态规划 -- 棋盘问题 POJ 1321

    一个 N * N 的棋盘上面,有些格子不能放,放置 M 的棋子, 每两个棋子不能在同一行或者同一列,问有多少种放法 DFS太慢,用SCR好点点 Python 仅仅有 22 行,事实上能够更短.可是得排 ...

随机推荐

  1. wutianqi 博客 母函数

    母函数(Generating function)详解 — Tanky Woo 在数学中,某个序列的母函数(Generating function,又称生成函数)是一种形式幂级数,其每一项的系数可以提供 ...

  2. lintcode-125-背包问题 II

    125-背包问题 II 给出n个物品的体积A[i]和其价值V[i],将他们装入一个大小为m的背包,最多能装入的总价值有多大? 注意事项 A[i], V[i], n, m均为整数.你不能将物品进行切分. ...

  3. 算法学习——kruskal重构树

    kruskal重构树是一个比较冷门的数据结构. 其实可以看做一种最小生成树的表现形式. 在普通的kruskal中,如果一条边连接了在2个不同集合中的点的话,我们将合并这2个点所在集合. 而在krusk ...

  4. [zoj] 3496 Assignment || 有源汇上下界最大流

    原题 贴个博客吧 #include<cstdio> #include<algorithm> #include<cstring> #define N 510 #def ...

  5. [Leetcode] Remove duplicates from sorted array ii 从已排序的数组中删除重复元素

    Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...

  6. [bzoj 2733]启发式合并权值线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2733 平衡树待学习.从一个博客学到了合并权值线段树的姿势:http://blog.csdn ...

  7. php 计算两个日期的间隔天数

    使用php内部自带函数实现 1.使用DateTime::diff 实现计算 参考阅读>>PHP DateTime::diff() 上代码: <?php $start = " ...

  8. 串的模式匹配算法(求子串位置的定位函数Index(S,T,pos))

    串的模式匹配的一般方法如算法4.5(在bo4-1.cpp 中)所示:由主串S 的第pos 个字 符起,检验是否存在子串T.首先令i 等于 pos(i 为S 中当前待比较字符的位序),j 等于 1(j ...

  9. java实现ssm框架的crud

    上一篇博客写了通过表名获取数据库表结构的demo,现在我以此为基础实现了一个简单的通过数据库表结构生成对应的实体,通过读取mapper接口文件.mapping映射文件. service映射文件模板,替 ...

  10. NSMutableArray遍历删除注意事项

      for (int i = 0; i < [array count]; i++) { [array removeObjectAtIndex:i]; } 上面的遍历由于在remove操作之后ar ...