码迷,mamicode.com
首页 > 其他好文 > 详细

组合数学 + dp

时间:2015-02-11 20:22:03      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

//CodeForces 232B

//原先 T 了的代码

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 using namespace std;
 6 const int mod = 1e9 + 7;
 7 __int64 dp[110][10100];
 8 __int64 c[110][110], f[110][2];
 9 __int64 n, m, k;
10 
11 __int64 modEXP(__int64 a,__int64 k)
12 {
13     __int64 res = 1;
14     while(k) {
15         if(k&1)
16             res *= a, res %= mod;
17         a *= a;
18         a %= mod;
19         k >>= 1;
20     }
21     return res;
22 }
23 
24 int main()
25 {
26     int i, j, r;
27     c[0][0] = 1;
28     for(i = 1; i<=100; ++i) {
29         c[i][0] = 1;
30         for(j = 1; j<=100; ++j)
31             c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
32     }
33     scanf("%I64d%I64d%I64d", &n, &m, &k);
34     __int64 cnt, rem;
35     cnt = m / n;
36     rem = m % n;
37     for(i = 0; i<=100; ++i) {
38         f[i][0] = modEXP(c[n][i], cnt);
39         f[i][1] = modEXP(c[n][i], cnt + 1);
40     }
41     dp[0][0] = 1;
42     for(i = 1; i <= n; ++i) {
43         for(j = 0; j <= k; ++j) {
44             for(r = 0; r <= n; ++r) {
45                 if(r > j)
46                     break;
47                 dp[i][j] += dp[i - 1][j - r] * f[r][i<=rem] % mod;
48                 dp[i][j] %= mod;
49             }
50         }
51     }
52     printf("%I64d\n", dp[n][k]);
53 }

 

滚去看了数据,才发现 C(n, k) == C(n, n - k) 这里有个优化,加上就过了

 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 #include "algorithm"
 5 #include "cmath"
 6 using namespace std;
 7 const int mod = 1e9 + 7;
 8 __int64 dp[110][10100];
 9 __int64 c[110][110], f[110][2];
10 __int64 n, m, k;
11 
12 __int64 modEXP(__int64 a,__int64 k)
13 {
14     __int64 res = 1;
15     while(k) {
16         if(k&1)
17             res *= a, res %= mod;
18         a *= a;
19         a %= mod;
20         k >>= 1;
21     }
22     return res;
23 }
24 
25 int main()
26 {
27     int i, j, r;
28     c[0][0] = 1;
29     for(i = 1; i<=100; ++i) {
30         c[i][0] = 1;
31         for(j = 1; j<=100; ++j)
32             c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
33     }
34     scanf("%I64d%I64d%I64d", &n, &m, &k);
35     if(n<sqrt(k<<1))
36         k = n*n - k;
37     __int64 cnt, rem;
38     cnt = m / n;
39     rem = m % n;
40     for(i = 0; i<=100; ++i) {
41         f[i][0] = modEXP(c[n][i], cnt);
42         f[i][1] = modEXP(c[n][i], cnt + 1);
43     }
44     dp[0][0] = 1;
45     for(i = 1; i <= n; ++i) {
46         for(j = 0; j <= k; ++j) {
47             for(r = 0; r <= n; ++r) {
48                 if(r > j)
49                     break;
50                 dp[i][j] += dp[i - 1][j - r] * f[r][i<=rem] % mod;
51                 dp[i][j] %= mod;
52             }
53         }
54     }
55     printf("%I64d\n", dp[n][k]);
56 }

 

组合数学 + dp

标签:

原文地址:http://www.cnblogs.com/AC-Phoenix/p/4286832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!