zoukankan      html  css  js  c++  java
  • POJ 3254 poj3254 Corn Fields

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

    思路:

    DP[i][j]=sum(dp[i-1][k]); i表示当前这一行,状态为j有多少种方案

    首先,i行能放牛的状态由前一行i-1决定。所以我们只要知道前一行的状态就知道这一行的方案。因此要初始化第一行的状态dp[1][i]

    要使当前这一行能用状态j表示则应瞒足两种条件

    1 与当前这一行的地形符合

    2 这一行状态与前一行的某一状态不冲突

    x&(x<<1)表示x的二进制是否有两个相邻的1相邻

    注意,初始化地形状态的时候,应该是0所在的位所构成的数

     1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <iostream>
     6 #include <queue>
     7 #include <stack>
     8 #include <cmath>
     9 #include <set>
    10 #include <algorithm>
    11 #include <vector>
    12 // #include<malloc.h>
    13 using namespace std;
    14 #define clc(a,b) memset(a,b,sizeof(a))
    15 #define LL long long
    16 const int inf = 0x3f3f3f3f;
    17 const double eps = 1e-5;
    18 const double pi = acos(-1);
    19 const LL MOD = 1e8;
    20 const int N=1<<13;
    21 // const LL p = 1e9+7;
    22 // inline int r(){
    23 //     int x=0,f=1;char ch=getchar();
    24 //     while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();}
    25 //     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    26 //     return x*f;
    27 // }
    28 
    29 int dp[15][N];
    30 int G[N];
    31 int line[N];
    32 bool judge1(int x){
    33     return (x&(x<<1));
    34 }
    35 
    36 bool judge2(int x,int y){
    37     return G[x]&line[y];
    38 }
    39 int main(){
    40     int m,n;
    41     while(~scanf("%d%d",&n,&m)){
    42         // clc(G,0);
    43         // clc(dp,0);
    44         // clc(line,0);
    45     for(int i=1;i<=n;i++){
    46         for(int j=1;j<=m;j++){
    47             int x;
    48             scanf("%d",&x);
    49             if(x==0){
    50                G[i]+=(1<<(m-j));
    51             }
    52         }
    53     }
    54 
    55     int k=0;
    56     for(int i=0;i<(1<<m);i++){
    57         if(!judge1(i)){
    58             line[k++]=i;
    59         }
    60     }
    61     for(int i=0;i<k;i++){
    62         if(!judge2(1,i))
    63             dp[1][i]=1;
    64     }
    65 
    66     for(int i=2;i<=n;i++){
    67         for(int j=0;j<k;j++){
    68             if(judge2(i,j))
    69                 continue;
    70             for(int f=0;f<k;f++){
    71                 if(judge2(i-1,f))
    72                     continue;
    73                 if(!(line[j]&line[f]))
    74                     dp[i][j]+=dp[i-1][f];
    75             }
    76         }
    77     }
    78     
    79     int ans=0;
    80     for(int i=0;i<k;i++){
    81         ans+=dp[n][i];
    82         ans%=MOD;
    83     }
    84     printf("%d
    ",ans);
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    【原创】贴片电容的测量方法。。。这是我从自己QQ空间转过来的,本人实操!
    CentOS6.4安装Apache+MySQL+PHP
    第一次在博客园写博客。。。新人
    C# 简单生成双色球代码
    从客户端中检测到有潜在危险的 Request.Form 值 方法
    经典实例
    js鼠标键禁用功能
    逻辑思维题
    C#运算符笔记
    C#基础
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5527951.html
Copyright © 2011-2022 走看看