• poj 3254 状态压缩


    Corn Fields
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 15285   Accepted: 8033

    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

    题意:1个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相邻。问有多少种放牛方案(一头牛都不放也是一种方案)
    题解:

    【解析】根据题意,把每一行的状态用二进制的数表示,0代表不在这块放牛,1表示在这一块放牛。首先很容易看到,每一行的状态要符合牧场的硬件条件,即牛必须放在能放牧的方格上。这样就能排除一些状态。另外,牛与牛之间不能相邻,这样就要求每一行中不能存在两个相邻的1,这样也能排除很多状态。然后就是根据上一行的状态转移到当前行的状态的问题了。必须符合不能有两个1在同一列(两只牛也不能竖着相邻)的条件。这样也能去掉一些状态。然后,上一行的所有符合条件的状态的总的方案数就是当前行该状态的方案数。

    【状态表示】dp[state][i]:在状态为state时,到第i行符合条件的可以放牛的方案数

    【状态转移方程】dp[state][i] =Sigma dp[state'][i-1] (state'为符合条件的所有状态)

    【DP边界条件】首行放牛的方案数dp[state][1] =1(state符合条件) OR 0 (state不符合条件)

     
    以上解析 转载需研读
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<map>
     7 #include<queue>
     8 #include<stack>
     9 #include<vector>
    10 #include<set>
    11 #define ll __int64
    12 #define mod 100000000
    13 using namespace std;
    14 int n,m;
    15 int a[1003];
    16 int b[1003];
    17 int dp[20][1003];
    18 int cnt=0;
    19 bool check(int x)
    20 {
    21     if(x&(x/2)) return false;
    22     else return true;
    23 }
    24 bool fun(int x,int k)
    25 {
    26     if(x&b[k]) return false;
    27     else return true;
    28 }
    29 int main()
    30 {
    31     scanf("%d %d",&m,&n);
    32     int exm;
    33     for(int i=0;i<(1<<n);i++){
    34         if(check(i))
    35             a[++cnt]=i;
    36     }
    37     memset(b,0,sizeof(b));
    38     for(int i=1;i<=m;i++)
    39         for(int j=1;j<=n;j++){
    40         scanf("%d",&exm);
    41         if(exm==0)
    42             b[i]+=(1<<(n-j));
    43     }
    44     for(int i=1;i<=cnt;i++){
    45         if(fun(a[i],1))
    46             dp[1][i]=1;
    47     }
    48     for(int i=2;i<=m;i++){
    49         for(int k=1;k<=cnt;k++){
    50         if(!fun(a[k],i)) continue;
    51         for(int j=1;j<=cnt;j++){
    52         if(!fun(a[j],i-1)) continue;
    53         if(a[k]&a[j]) continue;
    54         dp[i][k]=(dp[i][k]+dp[i-1][j])%mod;
    55         }
    56     }
    57    }
    58     int ans=0;
    59     for(int i=1;i<=cnt;i++)
    60         ans=(ans+dp[m][i])%mod;
    61     printf("%d
    ",ans);
    62     return 0;
    63 }
  • 相关阅读:
    bzoj1027
    bzoj1069
    poj2079
    poj2187
    bzoj2281
    bzoj2285
    bzoj1558
    bzoj1822
    bzoj1559
    bzoj1570
  • 原文地址:https://www.cnblogs.com/hsd-/p/7071286.html
Copyright © 2020-2023  润新知