poj3254(状压dp)

Corn Fields

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 19518   Accepted: 10243

Description

Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can‘t be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.

Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.

Input

Line 1: Two space-separated integers: M and N
Lines 2..M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)

Output

Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000.

Sample Input

2 3
1 1 1
0 1 0

Sample Output

9

Hint

Number the squares as follows:

1 2 3  4  

There are four ways to plant only on one squares (1, 2, 3, or 4),
three ways to plant on two squares (13, 14, or 34), 1 way to plant on
three squares (134), and one way to plant on no squares. 4+3+1+1=9.

题目应为状压dp入门题

设计好状态即可,方程并不难

依然把每行设计为状态,压缩到十进制数中,判断解是否可行即可

具体看代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

const int maxn=1<<12+10;

int dp[13][maxn];
int cur[13];
int ans[maxn];
int top;

int check(int x,int v){
    return !(ans[x]&cur[v]);
}

int main(){
    int n,m;
    int k;
    scanf("%d%d",&n,&m);
    for (int i=0;i<(1<<m);i++){
        if(!(i&(i<<1))) ans[++top]=i;将数左移一位后再与就可以判断原数是否01相间分布
    }
    for (int i=1;i<=n;i++)
         for (int j=1;j<=m;j++){
            scanf("%d",&k);
            if(!k) cur[i]+=(1<<(m-j));//因为图为 000111,而二进制数状态为从右到左,所以把其反过来,设不可行状态为1,就可以与以后状态比较,若与上值为真就说明状态不对
         }
    for (int i=1;i<=top;i++)
        if(check(i,1)) dp[1][i]=1;
    for (int i=2;i<=n;i++){
        for (int j=1;j<=top;j++){
            if(!check(j,i)) continue;
            for (int k=1;k<=top;k++){
                if(!check(k,i-1)) continue;
                 if(!(ans[j]&ans[k])) dp[i][j]=(dp[i][j]%100000000+dp[i-1][k]%100000000)%100000000;
            }
        }
    }
   int sum=0;
   for (int i=1;i<=top;i++) sum=(sum%100000000+dp[n][i]%100000000)%100000000;
   printf("%d\n",sum%100000000);
return 0;
}

原文地址:https://www.cnblogs.com/lmjer/p/9409526.html

时间: 2024-10-12 21:04:10

poj3254(状压dp)的相关文章

POJ3254 状压DP入门

题目:http://poj.org/problem?id=3254 因为&运算写成&&--导致调试了快一个小时代的代码没有搞定 关于建图: 1.题目中是1表示可以放牧,0表示不可以放牧,但是建图的时候,可以放牧的位用0表示,不可以放牧的位用1表示.原因如下: 假设可以放牧的位用1表示,不可以放牧的位用0表示,那么假设当前行状态时1010   想要放置1001 ,&运算的结果是1,但是显然不合法, 也就是说  设值状态的意义,以及怎么判断是不是合法,这个在做之前一定考虑清楚再

POJ3254 状压dp

          Corn Fields Time Limit: 2000MS   Memory Limit: 65536K       Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a

poj3254 状压dp 每行独立 入门水题

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18789   Accepted: 9880 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yum

poj 3254 Corn Fields 状压dp入门

// poj3254 状压dp入门 // dp[i][S]表示前i行第i行状态为S时放牧的情况 // S为十进制的二进制数形式如5为101表示第一列和第三列放牧的方法数 // 首先dp[0][S]合法的话就是1 // 状态转移方程为dp[i][S] = sigma(dp[i-1][V])(S与V是合法状态) // 最后的结果就是dp[n][S](S为所有的合法状态) // // 刚开始十分傻x的dp[0][S]置为get(S),...get(S)是其中1的个数 // 这又不是求放羊的数量,这是方

poj3254 Corn Fields (状压DP)

http://poj.org/problem?id=3254 Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7588   Accepted: 4050 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parc

poj3254(Corn Fields)状压dp

题意:在n*m(1<=n,m<=12)的矩阵上种植玉米,任意共边的方格不能同时种,并且有些特定方格也不能种.问能有多少种种植的方案: 解法:很经典的状压模型.先将每一行的合法状态求出来,12的时候最多377个合法状态.然后进行与行之间的状态转移.最坏复杂度12*(377^2) 代码: /**************************************************** * author:xiefubao **********************************

poj3254:基础状压dp

第二个状压dp 做过的第一个也是放牛问题,两头牛不能相邻 这个题多了一个限制,就是有些位置不能放牛 于是先与处理一下每一行所有不能放牛的状态,处理的过程直接对每一个不能放牛的状态或以下 ac代码: #include <iostream> #include <stdio.h> #include<string.h> #include<algorithm> #include<string> #include<ctype.h> using n

算法复习——状压dp

状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达到目的····此时熟悉相关的位运算就很重要了····以下是常见的一些需要位运算方法 然后说实话状压dp其它方面就和普通dp差不多了···它不像数位区间树形那样或多或少好歹有自己一定套路或规律····如何想到转移方程和状态也就成了其最难的地方··· 例题: 1.Corn Fields(poj3254)

ZOJ3305Get Sauce 状压DP,

状压DP的题目留个纪念,首先题意一开始读错了,搞了好久,然后弄好了,觉得DFS可以,最后超时,修改了很久还是超时,没办法看了一下n的范围,然后觉得状压可以,但是没有直接推出来,就记忆化搜索了一下,可是一直错,莫名奇妙,然后没办法看了一下题解,发现了下面这个比较好的方法,然后按照这个方程去推,然后敲,也是WA了好多把,写的太搓了,没人家的清楚明了,唉~也算是给自己留个纪念,状压一直做的都不太好~唉~还好理解了, 参考了  http://blog.csdn.net/nash142857/articl