题意:

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. 【方言】Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

    Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set 几种 方言配置差异 <?xml v ...

  2. java 中 sleep(1000) 和 wait(1000) 的区别?

    1.首先 sleep 方法是Thread类中的静态方法,他的作用是使当前线程暂时睡眠指定的时间,可以不用放在synchronized方法或者代码块中,但是 wait 方法是Object类的方法,它是使 ...

  3. 通过I2C总线向EEPROM中写入数据,记录开机次数

    没买板子之前,用protues画过电路图,实现了通过i2c总线向EEPROM中写入和读出数据. 今天,在自己买的板子上面写关于i2c总线的程序,有个地方忘了延时,调程序的时候很蛋疼.下面说说我对I2c ...

  4. 记一个菜鸟在Linux上部署Tomcat的随笔

    以前都只是在园子里找各种资料.文档.各种抱大腿,今天是第一次进园子里来添砖加瓦,实话说,都不知道整些啥东西上来,就把自己在Linux上搭建Tomcat的过程记录下来,人笨,请各位大虾们勿喷. 虽然做开 ...

  5. 2D多边形碰撞器优化器

    http://www.unity蛮牛.com/thread-19827-1-1.html http://pan.baidu.com/s/1qW2mWS8 Asset Store Link: http: ...

  6. POJ2201+RMQ

    /* RMQ */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<algo ...

  7. mac 浏览器 强刷快捷键

    windows 浏览器的刷新快捷键F5,强制刷新Ctrl+F5 Mac 系统下浏览器的刷新快捷键 command+R, 强制刷新快捷键为 command+shift+R

  8. comm命令——

    comm命令 :对已经有序的文件进行比较——第一列只在文件1中出现的文件,第二列只在文件2中出现的文件,第三列在文件1和文件2中同事出现的文件 请注意前提条件:             comm对文件 ...

  9. poj棋盘分割(记忆化)

    http://poj.org/problem?id=1191 黑书上P116 想了挺久 没想出来 想推出一公式来着 退不出来.. 想偏了  正解:递归 #include <iostream> ...

  10. bzoj2208

    首先有向图的题目不难想到先tarjan缩点 一个强连通分量中的点的连通数显然是相等: 据说这样直接dfs就可以过了,但显然不够精益求精 万一给定的是一个完全的DAG图怎么办,dfs铁定超时: 首先想, ...