POJ 3254 Corn Fields 状态压缩
这题对我真的非常难。实在做不出来,就去百度了,搜到了一种状压DP的方法。这是第一种
详细见凝视
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
using namespace std;
#define mod 100000000
int n,m,map[15];//map数组用来存图
int cnt[10000],dp[15][10000];//cnt存当一层每处都能够放置东西时,全部满足题意的情况
int k;
bool ok(int x)//推断某种方法是否满足题意
{
if(x&(x<<1)) return false; //假设某点左右有点的话,返回false
return true;
}
void find()
{
for(int i=0;i<(1<<m);i++) //从0開始到1<<m。找到全部单层满足题意的情况
{
if(ok(i)) cnt[k++]=i;
}
}
int main()
{
int i,j,temp;
while(cin>>n>>m)
{
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>temp;
if(!temp) map[i]|=1<<j;//此处存图应该注意。与题中相反的是,当某点不能够放置东西时,应该置为1。便于兴许操作
}
}
k=0;
memset(dp,0,sizeof(dp));
memset(cnt,0,sizeof(cnt));
find();
for(i=0;i<k;i++)//初始化第一行
{
if(!(map[0]&cnt[i]))
{
dp[0][i]=1;
}
}
for(i=1;i<n;i++)//从第二行開始进行递推
{
for(j=0;j<k;j++)
{
if(map[i-1]&cnt[j]) continue;
for(int p=0;p<k;p++)
{
if((map[i]&cnt[p])||(cnt[p]&cnt[j])) continue;
dp[i][p]=(dp[i][p]+dp[i-1][j])%mod;
}
}
}
int ans=0;
for(i=0;i<k;i++)//算出全部的情况
{
ans=(ans+dp[n-1][i])%mod;
}
cout<<ans<<endl;
}
return 0;
}
另外一种方法是状态压缩+记忆化搜索。这是我从瓜神那看来的记忆化搜索,然后依据我从上个代码中学来的东西改进了下,QAQ。要学的东西还有非常多。慢慢来吧
主要思路是从第一层開始向下搜索,假设搜到符合条件的就继续向下搜索,直到最后一行为止
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 20
#define mod 100000000
int map[maxn];
int dp[maxn][1<<12];
int n,m;
bool ok(int i,int state,int cur)
{
if(map[cur]&i) return false;//推断是否会把东西放在不能放东西的地方
if(i&(i<<1)) return false;//推断东西的左右是否放置了东西
if(cur)
{
if(state&i) return false;//推断东西的上边是否放置了东西
}
return true;
}
int dfs(int cur,int state)
{
if(cur==n) return dp[cur][state]=1;
if(dp[cur][state]!=-1) return dp[cur][state];//记忆化搜索
int ret=0;
for(int i=0;i<(1<<m);i++)
{
if(ok(i,state,cur))//推断下一条边能否够增加
{
ret+=dfs(cur+1,i);
ret%=mod;
}
}
return dp[cur][state]=ret%mod;
}
int main()
{
int t;
cin>>n>>m;
memset(map,0,sizeof(map));
memset(dp,-1,sizeof(dp));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>t;
if(!t) map[i]|=1<<j;
}
}
cout<<dfs(0,0)<<endl;
return 0;
}
POJ 3254 Corn Fields 状态压缩的更多相关文章
- 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 ...
- [ACM] POJ 3254 Corn Fields(状态压缩)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8062 Accepted: 4295 Descr ...
- POJ 3254 Corn Fields 状态压缩DP (C++/Java)
id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...
- POJ 3254 Corn Fields (状态压缩DP)
题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...
- POJ 3254 Corn Fields状态压缩DP
下面有别人的题解报告,并且不止这一个状态压缩题的哦···· http://blog.csdn.net/accry/article/details/6607703 下面是我的代码,代码很挫,绝对有很大的 ...
- poj - 3254 Corn Fields (状态压缩dp入门)
http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...
- poj 3254 Corn Fields 国家压缩dp
意甲冠军: 要在m行n陆行,有一些格您可以种树,别人做不到的.不相邻的树,我问了一些不同的共同拥有的法律. 分析: 从后往前种,子问题向父问题扩展,当种到某一格时仅仅有他和他后面的n-1个格子的情况对 ...
- poj 3465 Corn Fields 状态压缩
题目链接:http://poj.org/problem?id=3254 #include <cstdio> #include <cstring> #include <io ...
随机推荐
- [DM8168]Linux下控制GPIO控制12864液晶屏(ST7565控制器)
首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动函数: /* * fileName: st7565_driver.c * just for LCD12864 driver * GP ...
- [oldboy-django][1初识django]阻止默认事件发生 + ajax + 模态编辑对话框
阻止默认事件发生 a 阻止a标签默认事件发生方法 <a href="http://www.baidu.com" onclick="modalEdit();" ...
- Callable、Future、FutureTask浅析
1.Callable<V>接口 Runnable接口 public interface Runnable { public abstract void run(); } Callable ...
- Redis主从复制简单介绍
由于本地环境的使用,所以搭建一个本地的Redis集群,本篇讲解Redis主从复制集群的搭建,使用的平台是Windows,搭建的思路和Linux上基本一致! (精读阅读本篇可能花费您15分钟,略读需5分 ...
- 现代互联网的TCP拥塞控制(CC)算法评谈
动机 写这篇文章本质上的动机是因为前天发了一个朋友圈,见最后的写在最后,但实际上,我早就想总结总结TCP拥塞控制算法点点滴滴了,上周总结了一张图,这周接着那些,写点文字. 前些天,Linux中国微信公 ...
- leetcode 21 list merge
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...
- 【CF1015E】Stars Drawing(贪心)
题意:给定一个n×m大小的字符矩阵,仅由‘.’和‘*’组成,询问这个图可否划分为一些由‘*’组成的十字形状,这些十字之间可以有重叠, 如果存在方案则输出每个十字中心坐标与边长度,无解输出-1 n,m& ...
- t4-editor使用方法 Visual T4
原文发布时间为:2011-05-17 -- 来源于本人的百度文章 [由搬家工具导入] http://visualstudiogallery.msdn.microsoft.com/40a887aa-f3 ...
- c++基础(一)
c++中静态内存分配与动态内存分配:1.静态对象是有名字的变量, 我们直接对其进行操作 ,而动态对象是没有名字的变量我们通过指针间接地对它进行操作.(静态内存分配是因为在源码编译的时候,编译器就为变量 ...
- duilib入门简明教程 -- 前言(1) (转)
原文转自 :http://www.cnblogs.com/Alberl/p/3341956.html 关于duilib的介绍就不多讲了,一来不熟,二来小伙伴们想必已经对比了多个界面库,也无需赘 ...