题面
大秦为你打开题目传送门
题目描述
有 $n\times m$ 个格子的矩形,有些格子已经填充,其余格子用 $1\times 2$ 、 $2\times1$ 、$1\times1$ 的木块去填充,其中 $1\times1$ 的木块的使用个数必须 $≥c$ 且 $≤d$ ,$1\times2$ 和 $2\times1$ 的没有限制,求能把矩形都填满的方案数。
思路
首先出门右转这道题的削弱版。
然后这道题就简单了,直接在那道题的基础上,增加一维,然后多处理一个已填充和 $1\times1$ 的转移。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
#include<bits/stdc++.h> using namespace std;
typedef long long ll; typedef __int128 int128;
namespace FastIO { template<typename T> inline T read(T& x) { x = 0; int f = 1; char ch; while (!isdigit(ch = getchar())) if (ch == '-') f = -1; while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar(); x *= f; return x; } template<typename T, typename... Args> inline void read(T& x, Args &...x_) { read(x); read(x_...); return; } inline ll read() { ll x; read(x); return x; } }; using namespace FastIO;
const int P = 1e9 + 7;
int n, m, c, d; int a[110][110];
ll dp[2][1 << 11][25];
inline void Input() { read(m, n, c, d); for(int i = 1; i <= m; i++) { for(int j = 1; j <= n; j++) { scanf("%1d", &a[i][j]); } } }
inline void Work() { dp[0][(1 << n) - 1][0] = 1; int cur = 0; for(int i = 1; i <= m; i++) { for(int j = 1; j <= n; j++) { cur ^= 1; for(int k = 0; k <= d; k++) { for(int mask = 0; mask < (1 << n); mask++) { if(a[i][j] == 0) { if(mask & (1 << j - 1)) { (dp[cur][mask][k] += dp[cur ^ 1][mask][k]) %= P; } } else { if((mask & (1 << j - 1))) { (dp[cur][mask][k + 1] += dp[cur ^ 1][mask][k]) %= P; } if(j > 1 && !(mask & (1 << (j - 2))) && (mask & (1 << j - 1))) { (dp[cur][mask | (1 << (j - 2))][k] += dp[cur ^ 1][mask][k]) %= P; } (dp[cur][mask ^ (1 << j - 1)][k] += dp[cur ^ 1][mask][k]) %= P; } } } memset(dp[cur ^ 1], 0, sizeof(dp[cur ^ 1])); } } ll ans = 0; for(int i = c; i <= d; i++) { ans += dp[cur][(1 << n) - 1][i]; ans %= P; } printf("%lld", ans); }
int main() { int T = 1; while(T--) { Input(); Work(); } return 0; }
|