zoukankan      html  css  js  c++  java
  • CodeForcesGym 100212E Long Dominoes

    Long Dominoes

    Time Limit: 1000ms
    Memory Limit: 65536KB
    This problem will be judged on CodeForcesGym. Original ID: 100212E
    64-bit integer IO format: %I64d      Java class name: (Any)

    Find the number of ways to tile an m*n rectangle with long dominoes -- 3*1 rectangles.

    Each domino must be completely within the rectangle, dominoes must not overlap (of course, they may touch each other), each point of the rectangle must be covered.


    Input

    The input contains several cases. Each case stands two integers m and n (1 <= m <= 9, 1 <= n <= 30) in a single line. The input ends up with a case of m = n = 0.


    Output

    Output the number of ways to tile an m*n rectangle with long dominoes.


    Sample Input

    3 3
    3 10
    0 0
    

    Sample Output

    2
    28
    

     

    Source

    Author

    Andrew Stankevich
     
    解题:状压dp
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int maxn = 1<<18;
     5 LL dp[2][maxn];
     6 vector<int>g[maxn];
     7 bool tab[10][10];
     8 int stx[maxn],tot;
     9 void dfs(int row,int st,int n) {
    10     if(row == n) {
    11         int tst = 0;
    12         for(int i = n-1; i >= 0; --i) {
    13             tst <<= 2;
    14             tst |= tab[i][1]|(tab[i][2]<<1);
    15         }
    16         g[tst].push_back(st);
    17         stx[tot++] = tst;
    18         stx[tot++] = st;
    19         return;
    20     }
    21     if(!tab[row][0]) {
    22         if(!tab[row][1] && !tab[row][2]) {
    23             tab[row][0] = tab[row][1] = tab[row][2] = true;
    24             dfs(row + 1,st,n);
    25             tab[row][0] = tab[row][1] = tab[row][2] = false;
    26         }
    27         if(row + 3 > n || tab[row + 1][0] || tab[row + 2][0]) return;
    28         tab[row + 2][0] = tab[row + 1][0] = tab[row][0] = true;
    29         dfs(row + 3,st,n);
    30         tab[row + 2][0] = tab[row + 1][0] = tab[row][0] = false;
    31     } else dfs(row + 1,st,n);
    32 }
    33 void init(int st,int n) {
    34     memset(tab,false,sizeof tab);
    35     for(int i = 0,xst = st; i < n; ++i,xst >>= 2) {
    36         int row = xst&3;
    37         tab[i][0] = row&1;
    38         tab[i][1] = (row>>1)&1;
    39         if(row == 2) return;
    40     }
    41     dfs(0,st,n);
    42 }
    43 int main() {
    44     freopen("dominoes.in","r",stdin);
    45     freopen("dominoes.out","w",stdout);
    46     int m,n;
    47     scanf("%d%d",&m,&n);
    48     for(int i = 0; i < (1<<(m + m)); ++i) init(i,m);
    49     sort(stx,stx + tot);
    50     tot = unique(stx,stx + tot) - stx;
    51     int cur = dp[0][0] = 1;
    52     for(int i = 1; i <= n; ++i) {
    53         for(int j = 0; j < tot; ++j) {
    54             for(int k = g[stx[j]].size()-1; k >= 0; --k)
    55                 dp[cur][stx[j]] += dp[cur^1][g[stx[j]][k]];
    56         }
    57         cur ^= 1;
    58         memset(dp[cur],0,sizeof dp[cur]);
    59     }
    60     printf("%I64d
    ",dp[cur^1][0]);
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    Mythological VI
    新访问计划
    数学小记
    【Learning】带花树——一般图最大匹配
    朋友
    【bzoj 1414】对称的正方形 单调队列+manacher
    【半集训记录】
    【codeforces 718E】E. Matvey's Birthday
    【codeforces 718 C&D】C. Sasha and Array&D. Andrew and Chemistry
    【bzoj 3233】[Ahoi2013]找硬币 ——搜索
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4857717.html
Copyright © 2011-2022 走看看