zoukankan      html  css  js  c++  java
  • ZOJ 2673 Hexagon and Rhombic Dominoes (状态压缩+dp)

    题意:由6n^2个小三角形组成的正六边形,问你用两个小三角菱形去填满有多少种方法

    解题思路:状态压缩+dp(因为只有一部分小三角形对下一层有影响)。。分上下讨论(不同的规则),情况比较多!

    解题代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<map>
      4 #include<vector>
      5 #include<cmath>
      6 #include<cstdlib>
      7 #include<stack>
      8 #include<queue>
      9 #include <iomanip>
     10 #include<iostream>
     11 #include<algorithm>
     12 #pragma comment(linker,"/STACK:102400000,102400000")
     13 
     14 using namespace std ;
     15 
     16 long long pos[100];
     17 long long num[30];
     18 long long dp[20][40000]; 
     19 long long row , zt , limits[30] ,n; 
     20 long long su[30];
     21 void dfs(long long  pop,long long status)
     22 {
     23     if(pop == su[row+1] )
     24     {
     25         dp[row+1][status] +=  dp[row][zt];
     26         return ;
     27     }
     28 
     29     if(row+1 <= n){
     30 
     31         if(pop % 2 == 0 ){      
     32             if(pop + 1 < su[row+1] && num[pop] == 0 ) 
     33             {   
     34                 dfs(pop+2,status);
     35                 dfs(pop+1,status+pos[pop/2]);
     36             }
     37             else 
     38                 dfs(pop+1,status+pos[pop/2]);
     39         }
     40         else {
     41             if(num[pop-1])
     42                 dfs(pop+1,status);
     43             else {
     44                 dfs(pop+2,status);
     45             }
     46         }
     47 
     48     }
     49     else {
     50         if(pop % 2 == 1 ){
     51             if(row == n?num[pop+1] == 0: num[pop+2] ==  0)
     52             {   
     53                 if(pop + 2 == su[row+1])
     54                     dfs(pop+2,status);
     55                 else{
     56                     dfs(pop+2,status);
     57                     dfs(pop+1,status + pos[pop/2]);
     58                 }
     59             }
     60             else
     61                 dfs(pop+1,status+pos[pop/2]);
     62         }
     63         else {
     64             if(row == n ? num[pop]:num[pop+1])
     65                 dfs(pop+1,status);
     66             else {
     67                 if(pop + 1 < su[row+1])
     68                     dfs(pop+2,status);
     69             }
     70 
     71         }    
     72 
     73     }
     74 
     75 }
     76 void change(long long k)
     77 {
     78     memset(num,0,sizeof(num));
     79     long long m = k ; 
     80     long long t = -2 ; 
     81     while(m)
     82     {
     83         t = t+2; 
     84         num[t] = m%2;
     85         m = m/2;
     86     }
     87 
     88 } 
     89 void change1(long long k)
     90 {
     91     memset(num,0,sizeof(num));
     92     long long m = k ; 
     93     long long t = -1 ; 
     94     while(m)
     95     {
     96         t = t+2; 
     97         num[t] = m%2;
     98         m = m/2;
     99     }
    100 } 
    101 int main()    
    102 {
    103     pos[0] = 1;
    104     for(long long i = 1;i <= 18; i ++ )
    105     {
    106         pos[i] = 2* pos[i-1];    
    107     }
    108 
    109     memset(limits,0,sizeof(limits));
    110     int t  = 0;
    111     while(scanf("%lld",&n)!=EOF)
    112     {
    113         t ++;
    114         for(long long i = 1;i <= n;i ++)
    115             limits[i] = n+i;
    116         for(long long i = n+1 ;i <= 2*n ;i ++)
    117             limits[i] =  limits[2*n -i+1] -1;
    118         for(long long i = 1;i <= n;i ++)
    119             su[i] = 2*(n+i) - 1; 
    120         for(long long i = n+1; i <= 2*n ;i ++)
    121             su[i] =  su[2*n-i+1];
    122 
    123 
    124 
    125         memset(dp,0,sizeof(dp));
    126         dp[0][0] = 1; 
    127         for(row = 0 ; row < 2*n ; row ++)
    128             for(zt = 0 ; zt < pos[limits[row]+1]; zt ++)
    129             {
    130                 if(dp[row][zt])
    131                 {
    132                     if(row <= n) 
    133                         change(zt);
    134                     else 
    135                         change1(zt);
    136                     dfs(0,0); 
    137                 }
    138             }
    139         if(t!= 1 )
    140             printf("
    ");
    141 
    142         printf("%lld
    ",dp[2*n][0]);
    143     }
    144     return 0 ; 
    145 
    146 }
    View Code

    ps:AC这道题 这是今天最爽的时候

    没有梦想,何谈远方
  • 相关阅读:
    CodeForces
    [AHOI 2013] 差异
    BZOJ
    [校内训练20_09_15]ABC
    [校内训练20_09_10]ABC
    [校内训练20_09_08]AC
    fastIO
    [校内训练20_06_05]ABC
    [校内训练20_06_04]ABC
    [校内训练20_06_03]ABC
  • 原文地址:https://www.cnblogs.com/zyue/p/3313188.html
Copyright © 2011-2022 走看看