POJ3254:Corn Fields(状态压缩)

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.

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

int n,m;
int a[15][15],dp[15][1<<12],v[1<<12];
const int mod = 100000000;

void init()
{
    int i,l = 0;
    for(i = 0; i<(1<<12); i++)
    {
        if((i & i<<1) == 0)//选出所有相邻不等的状态
            v[l++] = i;
    }
}

int check(int x,int p)
{
    for(int i = 1; i<=m; i++)
        if((p & 1<<(i-1)) && !a[x][i])//不能放的地方放了
            return 1;
    return 0;
}

int main()
{
    int i,j,k;
    init();
    while(~scanf("%d%d",&n,&m))
    {
        for(i = 1; i<=n; i++)
            for(j = 1; j<=m; j++)
                scanf("%d",&a[i][j]);
        memset(dp,0,sizeof(dp));
        for(i = 1; i<=n; i++)
        {
            for(j = 0; v[j]<(1<<m); j++)
            {
                if(check(i,v[j])) continue;
                if(i == 1)
                {
                    dp[i][j] = 1;
                    continue;
                }
                for(k = 0; v[k]<(1<<m); k++)
                {
                    if((v[j]&v[k]) == 0)//与上一行没有相邻的
                        dp[i][j]+=dp[i-1][k];
                }
            }
        }
        __int64 ans = 0;
        for(i = 0; v[i]<(1<<m); i++)
            ans = (ans+dp[n][i])%mod;
        printf("%I64d\n",ans);
    }

    return 0;
}

POJ3254:Corn Fields(状态压缩)

时间: 2024-11-08 13:39:29

POJ3254:Corn Fields(状态压缩)的相关文章

POJ3254 Corn Fields 状态压缩DP

题目大意是在一块M行N列的农场上种谷物,但是不希望彼此相邻(共用一条边),并且有些地方不能种植谷物,给定M,N(范围都不超过12)以及一些不能种谷物的位置,求出一共有多少种方法种谷物. 状态压缩DP,设dp(i, k) 为种到第i行时,第i行状态为k的总共方案数,可以知道dp(i, k) = ∑dp(i -1, k'),其中我们要判断彼此相邻的情况以及不能种植的情况即可. #include <stdio.h> #include <vector> #include <math.

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

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

POJ 3254 Corn Fields(状态压缩DP)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 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 yumm

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

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8062   Accepted: 4295 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 yumm

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

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9806   Accepted: 5185 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 yumm

Poj 3254 Corn Fields(状态压缩)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8291   Accepted: 4409 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 yumm

POJ 3254 Corn Fields 状态压缩DP

题目链接:http://poj.org/problem?id=3254 思路:状态压缩DP,状态方程为dp[i][j] += (dp[i-1][k]) code: #include <stdio.h> #include <string.h> #define N 500 const int MOD = 100000000; int dp[15][N],ant[N],n,m,k,map[15]; bool ok(int x) { if(x&(x<<1))return

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

http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米,但是有的土地很贫瘠,所以不能种,每块土地标为1的表示能种,标为0的表示不能种,并且种玉米的土地不能相邻, 问有多少种合法的种植方案.(全部不种也算一种) 第一道状压,理解了比较久的时间. 就是用二进制的0和1代表土地种还是不种,这样每一行都可以用一个2进制数表示,列数<=12,故最多有2<<

poj3254 Corn Fieldsdp 状态压缩

一,题意: 给定一个N*M的矩阵,矩阵每个格子中只可能有两个数字0,1,1表示该土地肥沃可以种草放牛. 0表示该土地不肥沃不可以种草放牛.且牛不能放在相邻的位置,问有多少种放牛的方法. 二,解析: 该题主要应用了图的位压缩成数的思想与递推的思想,即压缩dp. 三,代码: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace