POJ3254Corn Fields(状压DP)
题意:
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)的更多相关文章
- 【POJ3254】Corn Fields 状压DP第一次
!!!!!!! 第一次学状压DP,其实就是运用位运算来实现一些比较,挺神奇的.. 为什么要发“!!!”因为!x&y和!(x&y)..感受一下.. #include <iostre ...
- POJ 3254 Corn Fields (状压dp)
题目链接:http://poj.org/problem?id=3254 给你n*m的菜地,其中1是可以种菜的,而菜与菜之间不能相邻.问有多少种情况. 状压dp入门题,将可以种菜的状态用一个数的二进制表 ...
- [ An Ac a Day ^_^ ] POJ 3254 Corn Fields 状压dp
题意: 有一块n*m的土地 0代表不肥沃不可以放牛 1代表肥沃可以放牛 且相邻的草地不能同时放牛 问最多有多少种放牛的方法并对1e8取模 思路: 典型的状压dp 能状态压缩 能状态转移 能状态压缩的题 ...
- P1879 [USACO06NOV]玉米田Corn Fields 状压dp/插头dp
正解:状压dp/插头dp 解题报告: 链接! ……我真的太菜了……我以为一个小时前要搞完的题目调错误调了一个小时……90分到100我差不多搞了一个小时…… 然后这题还是做过的……就很气,觉得确实是要搞 ...
- POJ 1684 Corn Fields(状压dp)
描述 Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ ...
- POJ 3254 - Corn Fields - [状压DP水题]
题目链接:http://poj.org/problem?id=3254 Time Limit: 2000MS Memory Limit: 65536K Description Farmer John ...
- [USACO06NOV]玉米田Corn Fields 状压DP
题面: 农场主John新买了一块长方形的新牧场,这块牧场被划分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一块正方形的土地.John打算在牧场上的某几格里种上美味的草,供他的 ...
- [USACO06NOV]玉米田Corn Fields (状压$dp$)
题目链接 Solution 状压 \(dp\) . \(f[i][j][k]\) 代表前 \(i\) 列中 , 已经安置 \(j\) 块草皮,且最后一位状态为 \(k\) . 同时多记录一个每一列中的 ...
- poj3254Corn Fields(状压)
http://poj.org/problem?id=3254 第一个状压题 思路挺好想 用二进制表示每行的状态 然后递推 用左移 右移来判断是不是01间隔出现 c大神教的 我的代码WA在这个地方了.. ...
随机推荐
- 大话string
最近看完大话string之后深有感悟,虽然写c#不知不觉的已经写了四年了,但是很多原理也一直不太明白,最近看完这个才算略微明白了一些. string类型有2个重要的特性,一致性和驻留性. 一致性就是说 ...
- 如何让listview列表为空时显示提示
先在布局文件中声明一个TextView,再设置listview.setEmptyView(TextView).这样当listview中的数据为空时就会列表的位置就会显示textviw中的提示.
- linux环境下验证码不显示的几种情况
linux环境下验证码不显示的几种情况 gd库扩展没有安装. 查看phpinfo(),看看有没有安装gd库 yum安装gd库或者phpize安装 安装完成后记得重启php-fpm bom头的原因 在生 ...
- location.search 详解
JS中location.search什么意思 设置或获取网页地址跟在问号后面的部分 当以get方式在url中传递了请求参数时,可以利用location的search属性提取参数的值,下面的代码把参数的 ...
- 教你6步定制你的Ubuntu桌面
转自教你6步定制你的Ubuntu桌面 对于那些想要一个易于使用的界面的用户,Ubuntu是一个很好的Linux发行版,并且对于一个Linux新手也可以说是最好的Linux发行版.不过这产生了一些副作用 ...
- MD5算法步骤详解
转自MD5算法步骤详解 之前要写一个MD5程序,但是从网络上看到的资料基本上一样,只是讲了一个大概.经过我自己的实践,我决定写一个心得,给需要实现MD5,但又不要求很高深的编程知识的童鞋参考.不多说了 ...
- java复制文件的4种方式
尽管Java提供了一个可以处理文件的IO操作类.但是没有一个复制文件的方法.复制文件是一个重要的操作,当你的程序必须处理很多文件相关的时候.然而有几种方法可以进行Java文件复制操作,下面列举出4中最 ...
- 正则表达式(javascript)学习总结
正则表达式在jquery.linux等随处可见,已经无孔不入.因此有必要对这个工具认真的学习一番.本着认真.严谨的态度,这次总结我花了近一个月的时间.但本文无任何创新之处,属一般性学习总结. 一.思考 ...
- Android 内核初识(6)SystemServer进程
简介 SystemServer的进程名实际上叫做“system_server”,通常简称为SS. 系统中的服务驻留在其中,常见的比如WindowManagerServer(Wms).ActivityM ...
- keytool 错误: java.io.FileNotFoundException: 拒绝访问
keytool 错误: java.io.FileNotFoundException: 拒绝访问 打开命令行,切换到D:\AndroidStudioProjects\MyApplication\app目 ...