zoukankan      html  css  js  c++  java
  • Corn Fields(poj

     题目链接:http://poj.org/problem?id=3254

      

     题意:

      一个n*m的矩形,告诉你哪些格子可以放棋子,哪些格子不能放(1表示能放,0表示不能放)。且相邻格子不能放。问一共有多少种放棋子的方案。(一个棋子也不放算一种方案,答案对1e8取模)。

     题解:

      状态压缩递推。

      设dpi,s表示第i行,方案为s(s为一个用来记录方案的二进制数,被选列为1,不被选列为0)。则dpi,s = sum{dpi-1,ss||s&ss==0} [s合法] || 0 [s不合法](s合法的判断标准为是否选了左右相邻格子,s&ss==0判断的是是否选了上下相邻格子) 。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define LL long long
     5 #define RI register int
     6 #define KI 100000000
     7 using namespace std;
     8 const int INF = 0x7ffffff ;
     9 const int N = 12 + 2 ;
    10 
    11 inline int read() {
    12     int k = 0 , f = 1 ; char c = getchar() ;
    13     for( ; !isdigit(c) ; c = getchar())
    14       if(c == '-') f = -1 ;
    15     for( ; isdigit(c) ; c = getchar())
    16       k = k*10 + c-'0' ;
    17     return k*f ;
    18 }
    19 int n, m ;
    20 bool v[N][N] ; int dp[N][1<<N] ;
    21 
    22 int main() {
    23     n = read(), m = read() ;
    24     for(int i=1;i<=n;i++) 
    25      for(int j=1;j<=m;j++) 
    26       v[i][j] = read() ;
    27     dp[1][0] = 1 ;
    28     for(int s=1;s<(1<<m);s++) {
    29         bool flag = 0 ;
    30         for(int j=1;j<=m;j++) {        
    31             if(!v[1][j] && s&(1<<(j-1))) {
    32                 flag = 1; break ;
    33             }
    34         }
    35         for(int j=1;j<m;j++) if(s&(1<<(j-1)) && s&(1<<j)) { flag = 1 ; break ; }
    36         if(!flag) dp[1][s] = 1 ;
    37     }
    38     for(int i=2;i<=n;i++) {
    39         for(int s=0;s<(1<<m);s++) {
    40             dp[i][s] = 0 ; bool flag = 0 ;
    41             for(int j=1;j<=m;j++) 
    42                 if(!v[i][j] && s&(1<<(j-1))) { // 该状态中有不能放的格子 
    43                     flag = 1 ; break ;
    44                 } 
    45             for(int j=1;j<m;j++) if(s&(1<<(j-1)) && s&(1<<j)) {
    46                 flag = 1 ; break ;
    47             }
    48             if(flag) continue ;
    49             for(int ss=0;ss<(1<<m);ss++)  { // 枚举上一行状态
    50                 if(ss&s) continue ; // 上下格相邻
    51                 dp[i][s] += dp[i-1][ss] ; dp[i][s] %= KI ;
    52             }
    53         }
    54     }
    55     int ans = 0 ;
    56 //    for(int s=0;s<(1<<m);s++) printf("%d %d
    ",s,dp[1][s]) ; 
    57     for(int s=0;s<(1<<m);s++) ans = (ans+dp[n][s])%KI ;
    58     printf("%d",ans) ;
    59     return 0 ;
    60 }
  • 相关阅读:
    职场“十不要”,让你少奋斗30年
    360与QQ在用户界面上的明显BUG
    urlMappings在asp.net2.0,asp.net4.0中的差异
    NHibernate主键生成方式
    MDaemon 常用视频教程
    sqlserver 差异备份与还原示例
    没有不死的爱情, 只有平淡的亲情——如何维系我们的婚姻
    25 个在 Web 中嵌入图表的免费资源
    atoi,atol,strtod,strtol,strtoul实现类型转换
    人生之精华,胜读十年书
  • 原文地址:https://www.cnblogs.com/zub23333/p/8631069.html
Copyright © 2011-2022 走看看