题意:

John 有一个豪华的M*N个格子组成的新牧场 他想种美味的玉米 但是有些位置不能种 而且他种地不选择相邻的格子 求所有可能的种地方法 (不种也算一种选择)
输入:第一行M和N, 第二行M*N地图,1代表该方格可以种地 0代表不可以种地
输出:方法数 % 100000000.

开始读题读错( no two chosen squares share an edge.)。。。

详细注释代码:

/*********************************************************
Problem: 3254 User: G_lory
Memory: 860K Time: 16MS
Language: G++ Result: Accepted
*********************************************************/
#include <cstdio>
#include <cstring> const int N = 13;
const int MAX = 1 << N;
const int MOD = 100000000; int st[MAX]; //根据每一行的列数,存储可能存在的状态
int map[MAX]; //存储原地图每一行的状态
int dp[N][MAX]; //对于每一行,每个状态可能的情况 bool judge(int x) //通过移位然后与运算判断一状态合不合法
{ //例如 10110 移位之后是
return x & (x << 1); //。。 01100 不为0证明至少有一位相邻
} bool judge(int a, int b) //通过与原地图与运算判断该状态是否合法
{
return map[a] & st[b];
} int main()
{
//freopen("in.txt", "r", stdin);
int m, n;
while (~scanf("%d%d", &n, &m)){
memset(map, 0 ,sizeof (map));
memset(st, 0 ,sizeof (st));
memset(dp, 0 ,sizeof (dp)); int x;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf("%d", &x);
if (!x) map[i] += 1 << (j - 1); //地图中存的是0的位置,这样就可以和其他状态直接与
}
}
int limit = 1 << m;
int cnt = 0;
for (int i = 0; i < limit; ++i) { //m位那么1<<m种状态,判断其中哪些状态是合法的
if (!judge(i))
st[cnt++] = i; //最终有cnt种合法状态
} for (int i = 0; i < cnt; ++i) { //第一行,合法那么该状态是一种可能
if (!judge(1, i))
dp[1][i] = 1;
} for (int i = 2; i <= n; ++i) { //第2-n行
for (int j = 0; j < cnt; ++j) {
if (judge(i, j)) continue; //如果该状态不满足地图继续
for (int k = 0; k < cnt; ++k) { //所有与该状态不冲突的上一行状态可能情况想加
if (!(st[j] & st[k])) dp[i][j] += dp[i - 1][k];
}
}
} int ans = 0;
for (int i = 0; i < cnt; ++i)
ans = (ans + dp[n][i]) % MOD;
printf("%d\n", ans);
}
return 0;
}

  

第二次做的代码(毕竟第一次是照着别人的代码写的)

/***************************************************************
Memory: 880 KB Time: 0 MS
Language: G++ Result: Accepted
****************************************************************/
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std; typedef long long ll; // (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) const int M = 12;
const int N = 12;
const int MAXN = 1 << N;
const int MOD = 100000000; int mp[M];
int dp[M][MAXN]; int m, n; bool judge(int i, int j)
{
return !(j & (j << 1)) && !(~mp[i] & j);
} void solve()
{
for (int i = 0; i < 1 << n; ++i) {
if (judge(0, i)) dp[0][i] = 1;
} for (int i = 1; i < m; ++i) {
for (int j = 0; j < 1 << n; ++j) {
if (judge(i, j)) {
int res = 0;
for (int k = 0; k < 1 << n; ++k) {
if (!(j & k)) {
res = (res + dp[i - 1][k]) % MOD;
}
}
dp[i][j] = res;
}
}
} int res = 0;
for (int i = 0; i < 1 << n; ++i)
res = (res + dp[m - 1][i]) % MOD; printf("%d\n", res);
} int main()
{
while (scanf("%d%d", &m, &n) != EOF) {
memset(dp, 0, sizeof dp);
for (int i = 0; i < m; ++i) {
int temp;
int res = 0;
for (int j = 0; j < n; ++j) {
scanf("%d", &temp);
res += temp * (1 << j);
}
mp[i] = res;
}
solve();
}
return 0;
}

  

  

POJ3254Corn Fields(状压DP)的更多相关文章

  1. 【POJ3254】Corn Fields 状压DP第一次

    !!!!!!! 第一次学状压DP,其实就是运用位运算来实现一些比较,挺神奇的.. 为什么要发“!!!”因为!x&y和!(x&y)..感受一下.. #include <iostre ...

  2. POJ 3254 Corn Fields (状压dp)

    题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...

  3. [ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp

    题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题 ...

  4. P1879 [USACO06NOV]玉米田Corn Fields 状压dp/插头dp

    正解:状压dp/插头dp 解题报告: 链接! ……我真的太菜了……我以为一个小时前要搞完的题目调错误调了一个小时……90分到100我差不多搞了一个小时…… 然后这题还是做过的……就很气,觉得确实是要搞 ...

  5. POJ 1684 Corn Fields(状压dp)

    描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...

  6. POJ 3254 - Corn Fields - [状压DP水题]

    题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...

  7. [USACO06NOV]玉米田Corn Fields 状压DP

    题面: 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地.John打算在牧场上的某几格里种上美味的草,供他的 ...

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

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

  9. poj3254Corn Fields(状压)

    http://poj.org/problem?id=3254 第一个状压题 思路挺好想 用二进制表示每行的状态 然后递推 用左移 右移来判断是不是01间隔出现 c大神教的 我的代码WA在这个地方了.. ...

随机推荐

  1. csv转json文件

    今天因为需要帮一个同事的新闻内容录入为html, 每次手改不方便,所以就弄了个csv(excel)转json的c++程序,然后再利用ejs把它渲染成网页,打开渲染好的网页再保存(不能保存源文件,不然还 ...

  2. 【JPA】两种不同的实现jpa的配置方法

    两种不同的实现jpa的配置方法 第一种: com.mchange.v2.c3p0.ComboPooledDataSource datasource.connection.driver_class=co ...

  3. 加解密算法二:非对称加解密及RSA算法的实现

    加密和解密使用不同的密钥的一类加密算法.这类加密算法通常有两个密钥A和B,使用密钥A加密数据得到的密文,只有密钥B可以进行解密操作(即使密钥A也无法解密):相反,使用密钥B加密数据得到的密文,只有密钥 ...

  4. JQ+AJAX实现多级联动

    利用JQ与AJAX实现三级联动实现的效果: 当前两级改变时,后边一级或两级都会改变: 使用的数据库: html代码: <!doctype html> <html lang=" ...

  5. PHP strip_tags() 函数

    定义和用法 strip_tags() 函数剥去 HTML.XML 以及 PHP 的标签. 语法 strip_tags(string,allow) 参数 描述 string 必需.规定要检查的字符串. ...

  6. Unicode编码的熟悉与研究过程(内附全部汉字编码列表)

    我有一个问题是:是不是会有个别汉字无法在Unicode下表示,这种情况下就不能完全显示了? 各种编码查询表:http://bm.kdd.cc/ ---------------------------- ...

  7. [Quick-x]移动CCEditbox的父对象导致输入框位置偏移问题

    CCEditbox对象添加到某个layer,当layer移动时候,editbox输入状态下输入光标保持在原位,看起来就是光标发生了偏移 如果开始时添加的editbox不在屏幕内的话,光标会出现在屏幕边 ...

  8. What is martian source / martian packets

    Martian source / Martian packets In Linux, by default, packets are considered individually for routi ...

  9. 先贴出代码C++ 中的单例模式

    先贴出代码,代码后面是讲解 自己编写的单例模式: #include <iostream> #include <stdio.h> #include <string> ...

  10. hdu4293Groups

    http://acm.hdu.edu.cn/showproblem.php?pid=4293 这题单拉出来写篇吧 确实不错的一题 将每个人说的话 转化一下 可以算出它处在哪个段中 题目就转换成了求不相 ...