ASC7 Problem D. Hexagon and Rhombic Dominoes

题目大意

给你一个边长为$n$的正六边形,问有多少种用规定的Dominoes牌覆盖的方案。

简要题解

状态压缩一下每行三角形的存在状态然后DP就好。

6和7跑不过去,然而这是一道打表好题。。

年轻人不要老想着打表。

慢慢剪状态。

1:用个set存上一行可能出现的状态,而不是枚举所有可能

2:大剪枝——只有当第i行出现的三角形数量为i时的状态才是有效状态。因为前面每一行都会多出一个Dominoes牌把腿伸到后面一行来QAQ

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 namespace my_header {
  4 #define pb push_back
  5 #define mp make_pair
  6 #define pir pair<int, int>
  7 #define vec vector<int>
  8 #define pc putchar
  9 #define clr(t) memset(t, 0, sizeof t)
 10 #define pse(t, v) memset(t, v, sizeof t)
 11 #define bl puts("")
 12 #define wn(x) wr(x), bl
 13 #define ws(x) wr(x), pc(' ')
 14     const int INF = 0x3f3f3f3f;
 15     typedef long long LL;
 16     typedef double DB;
 17     inline char gchar() {
 18         char ret = getchar();
 19         for(; (ret == '\n' || ret == '\r' || ret == ' ') && ret != EOF; ret = getchar());
 20         return ret; }
 21     template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) {
 22         for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar());
 23         if (c == '-') { flg = -1; c = getchar(); }
 24         for(ret = 0; '0' <= c && c <= '9'; c = getchar())
 25             ret = ret * 10 + c - '0';
 26         ret = ret * flg; }
 27     inline int fr() { int t; fr(t); return t; }
 28     template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); }
 29     template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
 30     template<class T> inline char wr(T a, int b = 10, bool p = 1) {
 31         return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 
 32             (wr(a/b, b, 0), pc('0' + a % b)));
 33     }
 34     template<class T> inline void wt(T a) { wn(a); }
 35     template<class T> inline void wt(T a, T b) { ws(a), wn(b); }
 36     template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); }
 37     template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); }
 38     template<class T> inline T gcd(T a, T b) {
 39         return b == 0 ? a : gcd(b, a % b); }
 40     template<class T> inline T fpw(T b, T i, T _m, T r = 1) {
 41         for(; i; i >>= 1, b = b * b % _m)
 42             if(i & 1) r = r * b % _m;
 43         return r; }
 44 };
 45 using namespace my_header;
 46 
 47 long long f[8][1<<14];
 48 
 49 bool ok(int t, int w, int s, int l) {
 50     for (int i = 0; i < w; ++i) {
 51         if (!(t & (1 << i))) {
 52             if (!(s & (1 << i))) {
 53                 s |= 1 << i;
 54             } else if (!(s & (1 << (i + 1)))) {
 55                 s |= 1 << (i + 1);
 56             } else {
 57                 return false;
 58             }
 59         }
 60     }
 61     return s == (1 << l) - 1;
 62 }
 63 
 64 set<int> S, T;
 65             
 66 
 67 int main() {
 68 #ifdef lol
 69     freopen("D.in", "r", stdin);
 70     freopen("D.out", "w", stdout);
 71 #else
 72     freopen("hex.in", "r", stdin);
 73     freopen("hex.out", "w", stdout);
 74 #endif
 75     int n = fr();
 76     f[0][0] = 1;
 77     S.insert(0);
 78     for (int i = 1; i <= n; ++i) {
 79         for (int j = 0; j < 1 << (i + n); ++j) {
 80             if (__builtin_popcount(j) != i)
 81                 continue;
 82             for (auto &&k : S)
 83                 if (ok(k, i + n - 1, j, i + n)) {
 84                     f[i][j] += f[i - 1][k];
 85                     T.insert(j);
 86                 }
 87         }
 88         S.swap(T);
 89         T.clear();
 90     }
 91     int s = 1 << (n + n);
 92     long long ans = 0;
 93     for (int i = 0; i < s; ++i) {
 94         //wt(f[n][i]);
 95         ans += f[n][i] * f[n][i];
 96     }
 97     wt(ans);
 98 
 99     return 0;
100 }

 

转载于:https://www.cnblogs.com/ichn/p/6405779.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值