POJ 3254 Corn Fields //入门状压dp

Corn Fields

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 7578   Accepted: 4045

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.

Source

USACO 2006 November Gold

/*
当上一行状态确定时,可以枚举下一行的状态;
*/
#include <stdio.h>
#include <string.h>
int a[15];
int dp[15][1<<13];

int main()
{
    int n, m;
    int i, j, k, v;
    int sum, x, all;

    while(scanf("%d%d", &m, &n)!=-1)
    {
        memset(dp, 0, sizeof(dp));
        memset(a, 0, sizeof(a));

        for(i=1; i<=m; i++)
            for(j=1; j<=n; j++)
            {
                scanf("%d", &v);
                a[i] |= (v<<(n-j));//a[i]存状态。如 5 就代表 0101
            }
        all = 1<<n;

        for(i=0; i<all; i++)//先枚举第一行的状态
        {
            if((a[1]|i)==a[1] && (i&(i<<1))==0)//当此时状态i中没有把牛放在没有草的地方 即 a[i]|i==a[1],当此时状态没有左右相邻的情况即i&(i<<1).
                                                //因为dp是从上往下,从左往右,所以不用在意右边与下面的情况
                dp[1][i]=1;
        }

        for(i=2; i<=m; i++)
        {
            for(j=0; j<all; j++)
            {
                x = dp[i-1][j];
                if(x!=0)        //当dp[i-1][j]==0时,代表这个点没草╮(╯_╰)╭
                {
                    for(k=0; k<all; k++)        //枚举通过dp[i-1][j]这个状态到达后面的所有状态
                    {
                        if((a[i]|k)==a[i] && (k&(k<<1))==0 && (k&j)==0)//当上一行的牛不和下一行相邻时就是(k&j)==0
                        {
                            dp[i][k] += x;
                        }
                    }
                }

            }
        }
        sum = 0;
        for(i=0; i<all; i++)    //最后一行的状态就是所求
            sum += dp[m][i];
        printf("%d\n", sum%100000000);
    }

    return 0;
}

POJ 3254 Corn Fields //入门状压dp

时间: 2024-12-06 05:36:14

POJ 3254 Corn Fields //入门状压dp的相关文章

POJ 3254 Corn Fields 【状压DP】

[题目大意]一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相邻.问有多少种放牛方案(一头牛都不放也是一种方案) [解析]根据题意,把每一行的状态用二进制的数表示,0代表不在这块放牛,1表示在这一块放牛.首先很容易看到,每一行的状态要符合牧场的硬件条件,即牛必须放在能放牧的方格上.这样就能排除一些状态.另外,牛与牛之间不能相邻,这样就要求每一行中不能存在两个相邻的1,这样也能排除很多状态.

POJ 3254 Corn Fields (状压DP,轮廓线DP)

题意: 有一个n*m的矩阵(0<n,m<=12),有部分的格子可种草,有部分不可种,问有多少种不同的种草方案(完全不种也可以算1种,对答案取模后输出)? 思路: 明显的状压DP啦,只是怎样压缩状态?跟轮廓线DP一样,按格子为单位来设计状态,一个状态只需要表示到其上方和左方的格子,所以最多只需要保存min(n,m)个01状态就行了(可以尝试旋转一下矩阵),最多需要12位.用哈希表来做会比较快吧,不用去考虑无效的状态,比如出现相邻两个1. 1 //#include <bits/stdc++.

POJ 3254 Corn Fields(状压dp)

题目链接:http://poj.org/problem? id=3254 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, s

POJ 3254 Corn Fields (状压DP)

题意:一个n*m的矩阵,每个格子是0或者1,1表示土壤肥沃可以种植草地,0则不可以.在种草地的格子可以放牛,但边相邻的两个格子不允许同时放牛,问总共有多少种放牛的方法?(不放牛也算一种情况) 思路:就是POJ 1185 炮兵阵地 的弱化版,炮兵那题相当于间隔两行,这里是间隔一行,减少一维坐标就可 //192 KB 32 ms C++ 1221 B #include<cstdio> #include<cstring> #include<algorithm> #includ

POJ 3254 Corn Fields (状压)

Language: Default Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8704   Accepted: 4641 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

【POJ 3254】 Corn Fields(状压DP)

[POJ 3254] Corn Fields(状压DP) Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10891   Accepted: 5705 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parce

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

poj 3254 Corn Fields ,状态压缩DP

题目链接 题意: 一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相邻.问有多少种放牛方案(一头牛都不放也是一种方案) state[i] 表示对于一行,保证不相邻的方案 状态:dp[i][ state[j] ]  在状态为state[j]时,到第i行符合条件的可以放牛的方案数 状态转移:dp[i][ state[j] ] =Sigma dp[i-1][state'] (state'为符合条

poj3254(Corn Fields)状压dp

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