• 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 }
  • 相关阅读:
    .dbmdl 文件
    where 命令一个快速定位工具所在的功能
    Window 2008 R2 软件限制策略的默认调整,导致记录事件日志的权限不足
    大家知道什么是 asp.net 呢 ?学习一下
    asp.net membership常见问题总结
    DivCSS布局实例:很实用的图文混排CSS列表
    js 在网页里让文本框只能输入数字的一种方法,外加回车换Tab
    从零开始学DedeCms模板,模板教程,从此模板制作不求人
    .net 数据类型
    常用正则表达式
  • 原文地址:https://www.cnblogs.com/zub23333/p/8631069.html
Copyright © 2020-2023  润新知