【HDOJ】5155 Harry And Magic Box

DP。dp[i][j]可以表示i行j列满足要求的组合个数,考虑dp[i-1][k]满足条件,那么第i行的那k列可以为任意排列(2^k),其余的j-k列必须全为1,因此dp[i][j] += dp[i-1][k]*(2^k)*C(j, k)。

 1 /* 5155 */
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 
 6 #define MAXN 51
 7 
 8 const __int64 MOD = 1e9+7;
 9 __int64 dp[MAXN][MAXN];
10 __int64 C[MAXN][MAXN];
11 __int64 two[MAXN];
12 
13 void init() {
14     int i, j, k, tmp;
15     
16     two[0] = 1;
17     for (i=1; i<MAXN; ++i) {
18         two[i] = (two[i-1] << 1);
19         two[i] %= MOD;
20     }
21     
22     C[1][0] = C[1][1] = 1;
23     for (i=2; i<MAXN; ++i) {
24         C[i][0] = C[i][i] = 1;
25         for (j=1; j<i; ++j) {
26             C[i][j] = C[i-1][j] + C[i-1][j-1];
27             C[i][j] %= MOD;
28         }
29     }
30     
31     for (i=0; i<MAXN; ++i)
32         dp[i][1] = dp[1][i] = 1;
33     
34     for (i=2; i<MAXN; ++i) {
35         for (j=1; j<MAXN; ++j) {
36             dp[i][j] = dp[i-1][j]*(two[j]-1)%MOD;
37             for (k=1; k<j; ++k) {
38                 dp[i][j] += dp[i-1][k]*C[j][k]%MOD*two[k];
39                 dp[i][j] %= MOD;
40             }
41         }
42     }
43 }
44 
45 int main() {
46     int n, m;
47     
48     #ifndef ONLINE_JUDGE
49         freopen("data.in", "r", stdin);
50         freopen("data.out", "w", stdout);
51     #endif
52     
53     init();
54     while (scanf("%d %d", &n, &m) != EOF)
55         printf("%I64d\n", dp[n][m]);
56     
57     return 0;
58 }

 

posted on 2015-01-22 10:06  Bombe  阅读(157)  评论(0编辑  收藏  举报

导航