【插头DP】HDU 4804 Campus Design

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4804

题意:用[C,D]个1×1的方格,和任意个1×2的方格去覆盖N*M的网格,有阻碍,的方法数。

思路:dp[cur][j][k]:当前状态为cur,用了j个1×1的方格时状态为k的方案数。

代码:

 1 #include <cstdio>  
 2 #include <cstring>
 3 
 4 const int MOD = 1000000007;  
 5 
 6 int n, m, c, d;
 7 long long dp[2][25][1222];  
 8 char g[105][15];  
 9   
10 int main() {  
11     while (4 == scanf("%d%d%d%d", &n, &m, &c, &d)) {  
12         int maxs = 1 << m;  
13         int cur = 0;
14         memset(dp[cur], 0, sizeof dp[cur]);  
15         dp[cur][0][maxs - 1] = 1;  
16         for (int i = 0; i < n; ++i)  
17             scanf("%s", g[i]);  
18         for (int i = 0; i < n; ++i) {  
19             for (int j = 0; j < m; ++j) { 
20                 memset(dp[cur ^ 1], 0, sizeof dp[cur ^ 1]);  
21                 if (g[i][j] != '0') {  
22                     for (int k = 0; k <= d; ++k) {  
23                         for (int s = 0; s < maxs; ++s) {  
24                             if (k && (s >> j & 1))   
25                                 dp[cur ^ 1][k][s] = (dp[cur ^ 1][k][s] + dp[cur][k - 1][s]) % MOD;//放1X1  
26                             if (j && !(s&1<<(j-1)) && (s&1<<j))  
27                                 dp[cur ^ 1][k][s|1<<(j-1)] = (dp[cur ^ 1][k][s|1<<(j-1)] + dp[cur][k][s]) % MOD;//横放1X2  
28                             dp[cur ^ 1][k][s^1<<j] = (dp[cur ^ 1][k][s^1<<j] + dp[cur][k][s]) % MOD;//竖放1X2  
29                         }  
30                     }  
31                 }  
32                 else {  
33                     for (int k = 0; k <= d; ++k) {  
34                         for (int s = 0; s < maxs; ++s) {  
35                             if ((s&1<<j))  
36                                 dp[cur ^ 1][k][s] = (dp[cur ^ 1][k][s] + dp[cur][k][s]) % MOD;//不能放的情况,和放1X1类似  
37                         }  
38                     }  
39                 }  
40                 cur ^= 1;
41             }   
42         }  
43         long long ans = 0;  
44         for (int i = c; i <= d; i++)  
45             ans = (ans + dp[cur][i][maxs - 1]) % MOD;  
46         printf("%lld\n", ans);  
47     }  
48     return 0;  
49 }  
View Code

 

posted @ 2015-07-14 21:10  mithrilhan  阅读(204)  评论(0编辑  收藏  举报