• Mondriaan's Dream POJ


    题目链接:

    Mondriaan's Dream

     POJ - 2411 

    题目大意:就是给你一个n*m的矩阵,然后问你用2*1的矩阵和1*2的矩阵,有多少种方法能凑出来n*m的矩阵,在不会有重叠的前提下。

    具体思路:状压dp,对于1*2的矩阵,我们将这个方块构成的两块都标记为1;对于2*1的矩阵,我们将上面那个方块标记为0,下面那个方块标记为1.然后在具体判断的过程中,先判断第一行,

    011是合法的,01是非法的。。。就是1只能是相邻的为偶数个。然后接下来的若干行按位判断、

    当(i,j)为0,(i-1,j)为0的时候,这种时候是非法的。

    当(i,j)为0,(i-1,j)为1的时候,这种时候是合法。

    当(i,j)为1,(i-1,j)为0的时候,这种时候是合法的。

    当(i,j)为1,(i-1,j)为1的时候,并且(i,j+1)和(i-1,j+1)都为1,是合法的。

    前三种情况都右跳一个,最后一种情况右跳两个。

    具体的学习网址:https://blog.csdn.net/hopeztm/article/details/7841917

    AC代码:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<string>
     6 using namespace std;
     7 # define inf 0x3f3f3f3f
     8 # define ll long long
     9 const int maxn = 2e5 +100;
    10 const int N = (1ll<<11);
    11 ll dp[12][N],n,m;
    12 bool check(ll j)
    13 {
    14     ll i=0;
    15     while(i<m)
    16     {
    17         if (( (1ll<<i) & j ) == 0 )
    18             i++;
    19         else if(i == m-1 || ((j & (1ll<<(i+1ll))) ==0))
    20         {
    21             return false;
    22         }
    23         else
    24         {
    25             i+=2;
    26         }
    27     }
    28     return true;
    29 }
    30 bool judge(int pos_state,int head_state)
    31 {
    32     int i=m-1;
    33     while(i>=0)
    34     {
    35         int pos1=(pos_state&(1<<i));
    36         int pos2=(head_state&(1<<i));
    37         if(!pos1&&!pos2){return false;}
    38         if(!pos1&&pos2){i--;continue;}
    39         if(pos1&&!pos2){i--;continue;}
    40         if((i-1)>=0&&pos1&&pos2&&(pos_state&(1<<(i-1)))&&(head_state&(1<<(i-1)))){i-=2;continue;}
    41         return false;
    42     }
    43     return true;
    44 }
    45 int main()
    46 {
    47     while(~scanf("%lld %lld",&n,&m)&&(n+m))
    48     {
    49         memset(dp,0,sizeof(dp));
    50         if(m>n)
    51             swap(n,m);
    52         ll maxstate=(1ll<<m)-1;
    53         for(ll j=0; j<=maxstate; j++)
    54         {
    55             if(check(j))
    56             {
    57                 dp[0][j]=1;
    58             }
    59         }
    60         for(ll i=1; i<n; i++)
    61         {
    62             for(ll j=0 ; j <= maxstate ; j++)
    63             {
    64                 for(ll k=0; k <= maxstate ; k++)
    65                 {
    66                     if(judge(j,k))
    67                     {
    68                         dp[i][j]+=dp[i-1][k];
    69                     }
    70                 }
    71             }
    72         }
    73         printf("%lld
    ",dp[n-1][maxstate]);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    pugixml
    C++ 头文件的理解
    图像的特征
    光圈与景深
    Unix高级环境编程
    用libtommath实现RSA算法
    【linux+C】神器 vim + 指针相关客串
    【算法25】对称子字符串的最大长度
    设计并实现同时支持多种视频格式的流媒体点播系统
    递归再一次让哥震惊了
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10821460.html
Copyright © 2020-2023  润新知