zoukankan      html  css  js  c++  java
  • poj 3254 状压dp

    题意:给出一个n行m列的草地,1表示肥沃,0表示贫瘠,现在要把一些牛放在肥沃的草地上,但是要求所有牛不能相邻,问你有多少种放法。

    链接:点我

    定义状态dp【i】【j】,第 i 行状态为 j 的时候放牛的种数。

    去年暑假做过的题,现在忘光了

     1 #include <cstdio>
     2 #include <cstring>
     3 const int N = 13;
     4 const int M = 1<<N;
     5 const int mod = 100000000;
     6 int st[M],map[M];  //分别存每一行的状态和给出地的状态
     7 int dp[N][M];  //表示在第i行状态为j时候可以放牛的种数
     8 bool judge1(int x)  //判断二进制有没有相邻的1
     9 {
    10     return (x&(x<<1));
    11 }
    12 bool judge2(int i,int x)
    13 {
    14     return (map[i]&st[x]);
    15 }
    16 int main()
    17 {
    18     int n,m,x;
    19     while(~scanf("%d%d",&n,&m))
    20     {
    21         memset(st,0,sizeof(st));
    22         memset(map,0,sizeof(map));
    23         memset(dp,0,sizeof(dp));
    24         for(int i=1;i<=n;i++)
    25         {
    26             for(int j=1;j<=m;j++){
    27                 scanf("%d",&x);
    28                 if(x==0)
    29                     map[i]+=(1<<(j-1));
    30             }
    31 
    32         }
    33         int k=0;
    34         for(int i=0;i<(1<<m);i++){
    35             if(!judge1(i))
    36                 st[k++]=i;
    37         }
    38         for(int i=0;i<k;i++)
    39         {
    40             if(!judge2(1,i))
    41                 dp[1][i]=1;
    42         }
    43         for(int i=2;i<=n;i++)
    44         {
    45             for(int j=0;j<k;j++)
    46             {
    47                 if(judge2(i,j))  //判断第i行 假如按状态j放牛的话行不行。
    48                     continue;
    49                 for(int f=0;f<k;f++)    //上一行的状态
    50                 {
    51                     if(judge2(i-1,f))   //剪枝 判断上一行与其状态是否满足
    52                         continue;
    53                     if(!(st[j]&st[f]))
    54                         dp[i][j]+=dp[i-1][f];
    55                 }
    56             }
    57         }
    58         int ans=0;
    59         for(int i=0;i<k;i++){
    60             ans+=dp[n][i];
    61             ans%=mod;
    62         }
    63         printf("%d
    ",ans);
    64     }
    65     return 0;
    66 }
  • 相关阅读:
    结对编程作业
    4组-Alpha冲刺-2/6
    4组-Alpha冲刺-1/6
    结对编程作业
    4组 团队展示
    python多进程遇到的问题和解决
    GNS3第一次ping通
    前缀表达式计算(栈的使用)
    欧拉筛法(线性筛)素数
    拓扑排序
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4502352.html
Copyright © 2011-2022 走看看