CodeForces 232B 组合数学 + dp
//原先 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 }