题意:由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 }
ps:AC这道题 这是今天最爽的时候