这题对我真的非常难。实在做不出来,就去百度了,搜到了一种状压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 状态压缩的更多相关文章

  1. POJ 3254. Corn Fields 状态压缩DP (入门级)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 Descr ...

  2. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  3. [ACM] POJ 3254 Corn Fields(状态压缩)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8062   Accepted: 4295 Descr ...

  4. POJ 3254 Corn Fields 状态压缩DP (C++/Java)

    id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...

  5. POJ 3254 Corn Fields (状态压缩DP)

    题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...

  6. POJ 3254 Corn Fields状态压缩DP

    下面有别人的题解报告,并且不止这一个状态压缩题的哦···· http://blog.csdn.net/accry/article/details/6607703 下面是我的代码,代码很挫,绝对有很大的 ...

  7. poj - 3254 Corn Fields (状态压缩dp入门)

    http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...

  8. poj 3254 Corn Fields 国家压缩dp

    意甲冠军: 要在m行n陆行,有一些格您可以种树,别人做不到的.不相邻的树,我问了一些不同的共同拥有的法律. 分析: 从后往前种,子问题向父问题扩展,当种到某一格时仅仅有他和他后面的n-1个格子的情况对 ...

  9. poj 3465 Corn Fields 状态压缩

    题目链接:http://poj.org/problem?id=3254 #include <cstdio> #include <cstring> #include <io ...

随机推荐

  1. 优化脚本性能 Optimizing Script Performance

    This page gives some general hints for improving script performance on iOS. 此页面提供了一些一般的技巧,提高了在iOS上的脚 ...

  2. import组件的时候报错

    去webpack.base.js配置 resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.e ...

  3. linux命令 显示文件内容

    通过命令+文件名查看内容.如下命令可以查看.1, cat :由第一行开始显示文件内容:2,tac:从最后一行开始显示,可以看出tac与cat字母顺序相反:3,nl:显示的时候输出行号:4,more:一 ...

  4. 【转】 Linux中记录终端输出到txt文本文件

    转载: http://blog.csdn.net/tengh/article/details/41823883 一,把命令运行的结果保存到文件当中:用 > 把输出转向就可以了 例子: $ ls ...

  5. 使用libcurl提示 LNK2001的错误

    vs使用libcurl(static library),link时报错: error LNK2001: unresolved external symbol __imp__curl_easy_perf ...

  6. 【CF1068A】Birthday(签到)

    题意:有N种棋子,M个人,已有K种收藏,要求最小的每个人送的棋子数使得最坏情况下至少有L种新的收藏,无解输出-1 N,M,K,L<=1e18 思路: #include<cstdio> ...

  7. Zookeeper如何从官网下载和安装

    打开百度搜索,输入Zookeeper关键词,一般第一条搜索记录就是apache官网下载的地址 进入apache官网,由于是国外的网站,里面内容都是英文的,可以大概看下Zookeeper的描述和介绍,在 ...

  8. 【电脑使用经验】怎么查看无线网络中电脑的IP地址?

    1. 2. 3. 4. 5.

  9. Android build code command

    make bootimage -j8 make systemimage -j8

  10. hdu 4786(生成树)

    Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...