刚开始的思路是  把0-2^x的 所有状态枚举, 然后找符合条件的,   但是 发现 当12*12 时  1的数量x 超过64  这是个庞大的数字, 跟本就没法枚举;

想到用状态压缩,  但是 怎么压缩才行 ?

作为这是状态压缩入门题,  感觉 废了好大力气;

【思路】

把每一行  0/1状态  转换成 十进制的数, 每一行看成一个整体, 进行压缩,

【第一步】

先提前处理  相邻两项不符合条件的  例如   001 和 011  这样的就不符合 (违背相邻两项不种植条件)

【第二步】

为了可以找到符合条件的,  在进行输入时 处理,  把  输入的  010  进行 取反  得到的是  101    目的是 & =0;  找到当前行 满足条件的

例如 示例 第二行 010,  那么只有 010 和 000 才能放在这   010 取反为 101  ,  101 & 010  =0       101 & 000 =0    这是符合条件的

【第三步】

找到当前行符合条件的,  那么进行筛选, 筛选出 既不能与前一行 相邻, 又不能与 之前到找的 重复  ;

找到后 累加到当前行中, 用dp【】【】 存储

dp【i】【j】  代表 第 i 行  状态 j 时  符合条件数目;

方程 dp【i】【j】 = Sigma   dp 【i-1】【k】   k代表所有符合的 项

【代码】

//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r#define mem(a,b) memset(a,b,sizeof(a))
typedef long long ll;const int INF=0x3f3f3f3f;
const ll MOD=1e8;
const int MAXN=1e5+5;
const int N=1000;
ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x);x=(x*x);}return res;}
using namespace std;int dp[N][N];
int cur[MAXN];
int state[MAXN];
int cot;
int n,m;
void init()
{int bits= 1<<m;cot=0;for(int i=0;i<bits;i++){if( (i&(i<<1))==0 )// 去除相邻的两项state[++cot]=i;}
}
int main()
{while(~scanf("%d %d",&n,&m)){init();//提前处理所以不相邻的数据for(int i=1;i<=n;i++){int x;for(int j=1;j<=m;j++){scanf("%d",&x);if(x==0){cur[i]+= (1<< (m-j)); // 取反  目的是 将 后面的重复项去掉, 例如 010 取反为 101 & 010 =0}}}mem(dp,0);for(int i=1;i<=cot;i++){if( (state[i]&cur[1]) ==0)// 边界状态dp[1][i]=1;}/* for(int i=1;i<=cot;i++){printf("%d | %d\n",state[i],cur[i]);}*/for(int i=2;i<=n;i++)// 从第二行开始{for(int j=1;j<=cot;j++){if( (state[j]&cur[i])==0 ) //符合条件 当前行{for(int k=1;k<=cot;k++){if( ((state[k]&cur[i-1])==0) && ((state[k]&state[j])==0 ) )// 并且不与前一行重复,找到的两个值一样{//printf("%d***\n",state[k]);dp[i][j]= (dp[i][j]+ dp[i-1][k]) %MOD;}}}}}int ans=0;for(int i=1;i<=cot;i++)ans = (ans+dp[n][i])% MOD;printf("%d\n",ans);}
}
/*
12 12
1 0 1 0 1 0 1 0 1 1 1 1
0 0 1 0 0 1 0 0 0 1 1 1
1 0 0 0 1 1 0 1 0 0 0 1
1 0 1 1 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1
1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 1 0 1 0 1 0 1
1 1 0 1 0 1 1 0 1 0 1 0
0 0 0 1 0 1 0 1 0 1 0 0
1 0 0 0 1 0 1 0 1 0 0 0
1 0 1 0 1 0 1 1 0 1 0 1
*/

转载于:https://www.cnblogs.com/sizaif/p/9078436.html

POJ 3254 Corn Fields (状态压缩)相关推荐

  1. poj 3254 Corn Fields 状态压缩dp

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K       Description Farmer John has purchased a ...

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

    题目:http://poj.org/problem?id=3254 思路见代码: #include<iostream> using namespace std;const int MOD= ...

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

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

  4. 状态压缩dp入门 第一题 POJ 3254 Corn Fields

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6460   Accepted: 3436 Descr ...

  5. POJ - 3254 - Corn Fields

    线上题目: Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6936   Accepted: 3697 ...

  6. Poj - 3254 Corn Fields (状压DP)(入门)

    题目链接:https://vjudge.net/contest/224636#problem/G 转载于:https://blog.csdn.net/harrypoirot/article/detai ...

  7. POJ - 3254 Corn Fields(状压dp)

    题目链接:点击查看 题目大意:给出一个n*m的地图,有些位置不能放牧,然后放牧的条件是相邻两个格子不允许同时使用,问可行方案有几种 题目分析:因为给出的数据范围很小,并且放牧的状态是放或者不放,很容易 ...

  8. POJ 3254 Corn Fields [DP]

    题意:略. 思路:第一次做状态压缩的dp. 在这里说一下状态压缩的原则.因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量 ...

  9. POJ 3254 Corn Fields(状态压缩)

    题意:给你一个n*m的田地,每块田地可以种菜,0代表不能种,1可以,求有多少种方法 题解:炮兵布阵系列 #include<cstdio> #include<cstring> # ...

最新文章

  1. 绩效管理是什么?怎么做绩效管理?
  2. 虚函数实现的基本原理(转载)
  3. Linux Kernel 5.0 RC 7 发布
  4. Xamarin XAML语言教程使用Visual Studio创建XAML
  5. Windows下查看端口被占用问题和解决办法
  6. 宝洁侮辱女性?其公众号发文 “女人脚臭是男人的5倍”,官方回应了...
  7. 举例说明jquery插件的编写方法
  8. NOIP2016DAY1题解
  9. Hello JAVA World!
  10. 电子科技大学计算机学院图章,桂林电子科技大学印章管理暂行规定
  11. C# - 此应用无法在你的电脑上运行
  12. php表格显示成绩,学生成绩表格展示
  13. USB无线网卡配置ICS失败,你可以连接到SoftAP,但可能无法使用internet服务
  14. 【LeetCode刷题-中等】2. 两数相加(python c++)
  15. Godot 4.0中的基于有向距离场SDF(Signed Distance Field)的实时全局光照技术
  16. QLineEdit文件名正则表达式
  17. linux主机名和工作组的修改方法
  18. FPGA设计开发(基础课题):74LS160计数器芯片设计
  19. cad2016中选择全图字体怎么操作_CAD2016 软件安装教程
  20. linux c邮件客户端,[源码和文档分享]基于C语言和TCP Socket实现的Linux环境下的邮件收发客户端程序...

热门文章

  1. Delphi 7 定义你自己的事件
  2. Error: listen EADDRINUSE: address already in use :::5000
  3. redis 远程主机强迫关闭了一个现有的连接_如何在 Debian 10 上安装和配置 Redis 服务...
  4. “普通人,不要随便创业,安心拿工资过日子比啥都强”你怎么看?
  5. 网络推广运营主要做些什么
  6. 为什么大部分人会碌碌无为?
  7. 2021考研初试成绩多少分过线?
  8. 如果地球突然停止转动,那么接下来会发生什么?
  9. 直播的一般流程是什么?
  10. 直播卖货到底是不是卖人设?