• UESTC_冬马党 CDOJ 882


    冬马党

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
     

    终于到了冬马党与雪菜党决战的时候了,为了方便,他们的决战之地可看成一个n×m矩阵。

    决战前夜,冬马党安插在雪菜党中的内线告诉白学家Kuros,雪菜党已经在他们的决战之地埋下了地雷。

    白学家Kuros根据多年来扫雷的经验,推测出雪菜党一定不会在相邻的格子里都放地雷。(两个格子相邻指它们共享一条边)并且,根据先遣部队的探查,某些格子的土地非常坚硬,是不可能埋地雷的。

    为了冬马党最终的胜利,Kuros想知道,雪菜党总共有多少种方案来放地雷。

    Input

    输入第一行为两个整数nm,表示决战之地的大小。(1n12,1m12)

    接下来n行,每行m个数,0表示该土地不能放地雷,1表示该土地可以埋地雷。

    Output

    一行,一个整数,表示总的方案数,答案取100000000的余数。

    Sample input and output

    Sample InputSample Output
    2 3
    1 1 1
    0 1 0
    9

    Source

    2014 UESTC Training for Dynamic Programming
     
    解题报告
    f(i,j) 表示第i行摆放情况为j的方案数.
    用一个dfs进行转移.注意情况:
    1.上一行的这个位置已经放了地雷,那么这一行的这里肯定不能再放
    2.题目明确禁止这行的这个位置不允许放地雷.
    因为我的dfs没有检查同一行两枚地雷相同的情况(非法),所以转移的时候j必须合法,最后答案计数的时候j也必须合法.
    最重要的是。。。不要爆了long long(我挂了两发。。)
    代码用了滚动数组进行优化~
     
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 #include <algorithm>
     5 typedef long long ll;
     6 using namespace std;
     7 const ll mod = 100000000;
     8 ll f[2][1 << 13];
     9 bool g[15][15];
    10 int n,m,r,cur=0;
    11 
    12 void dfs(int pos,int val,ll add)
    13 {
    14   if (pos == -1)
    15    f[cur][val] = (f[cur][val] + add) % mod;
    16   else
    17    {
    18          if (val >> pos & 1 || !g[r][pos]) //上一行的这个位置已经放了地雷 / 这个地方不允许放地雷 
    19           dfs(pos-1,val & ~(1 << pos),add);
    20          else
    21           {
    22                 dfs(pos-1,val | (1 << pos),add);
    23                 dfs(pos-1,val,add);
    24        }
    25    } 
    26 }
    27 
    28 
    29 bool check(int x)
    30 {
    31    int pre = 0;
    32    for(int i = 0 ; i < m ; ++ i)
    33     {
    34         int newx = x >> i & 1;
    35         if (newx && pre)
    36          return false;
    37         pre = newx;
    38     }
    39    return true;
    40 }
    41 
    42 int main(int argc,char *argv[])
    43 {
    44   memset(g,true,sizeof(g));
    45   memset(f,0,sizeof(f));
    46   scanf("%d%d",&n,&m);
    47   for(int i = 0 ; i < n ; ++ i)
    48    for(int j = 0 ; j < m ; ++ j)
    49     {
    50         int temp;
    51         scanf("%d",&temp);
    52         if (!temp)
    53          g[i][j] = false;
    54     }
    55   r = 0;
    56   dfs(m-1,0 , 1);
    57   for(int i = 1 ; i < n ; ++ i)
    58     {
    59        cur ^= 1;
    60        r = i;
    61        for(int j = 0 ; j < (1 << m) ; ++ j) f[cur][j] = 0;
    62        for(int j = 0 ; j < (1 << m) ; ++ j)
    63         if (check(j))
    64          dfs(m-1,j,f[cur^1][j]);
    65       }
    66   int ans = 0;
    67   for(int i = 0 ; i < (1 << m) ; ++ i)
    68    if (check(i))
    69     ans = (ans + f[cur][i]) % mod;
    70   printf("%lld
    ",ans % mod);
    71   return 0;
    72 }
    No Pain , No Gain.
  • 相关阅读:
    csu 1965
    csu 1947 三分
    Codeforces 336C 0-1背包
    POJ 1743 后缀数组
    POJ 2774 后缀数组
    UVA 12333 大数,字典树
    POJ 2942 圆桌骑士
    POJ 1503 大整数
    POJ 2342 树的最大独立集
    POJ 3088 斯特林
  • 原文地址:https://www.cnblogs.com/Xiper/p/4480762.html
Copyright © 2020-2023  润新知