Codeforces 100548F - Color (组合数+容斥)
題目鏈接:http://codeforces.com/gym/100548/attachments
有n個(gè)物品 m種顏色,要求你只用k種顏色,且相鄰物品的顏色不能相同,問(wèn)你有多少種方案。
從m種顏色選k種顏色有C(m, k)種方案,對(duì)于k種顏色方案為k*(k-1)^(n-1)種。但是C(m, k)*k*(k-1)^(n-1)方案包括了選k-1,k-2...,2種方案。
題目要求剛好k種顏色,所以這里想到用容斥。
但是要是直接C(m, k)*k*(k-1)^(n-1) - C(m, k-1)*(k-1)*(k-2)^(n-1)的話,其實(shí)是多減的。
比如k=4,4種顏色1 2 3 4,有種染色方案是1 2 1 2,那么k-1的話1 2 3或者1 2 4也有染色方案是1 2 1 2,這里發(fā)現(xiàn)多減了。所以k-2還得加上。
所以公式就變成了
C(m, k)*( k*(k-1)^(n-1) - C(k, k-1)*(k-1)*(k-2)^(n-1)?+ C(k, k-2)*(k-2)*(k-3)^(n-1) ... )
中間的組合數(shù)C(k, i),可以用逆元來(lái)解決。C(m, k)則暴力即可。
1 //#pragma comment(linker, "/STACK:102400000, 102400000") 2 #include <algorithm> 3 #include <iostream> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <ctime> 10 #include <list> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef __int64 LL; 15 typedef pair <int, int> P; 16 const int N = 1e6+ 5; 17 LL mod = 1e9 + 7; 18 LL f[N]; 19 20 LL Pow(LL a , LL n , LL mod) { 21 LL res = 1; 22 while(n) { 23 if(n & 1) 24 res = res * a % mod; 25 a = a * a % mod; 26 n >>= 1; 27 } 28 return res; 29 } 30 31 LL Cnm(LL n, LL m, LL mod) { 32 if(n < N) { //數(shù)據(jù)范圍小的 逆元就好了 33 return f[n]*Pow(f[m]*f[n-m]%mod, mod - 2, mod) % mod; 34 } 35 LL res = Pow(f[m]%mod, mod - 2, mod)%mod; 36 for(LL i = 0; i < m; ++i) { 37 res = res * (n-i) % mod; 38 } 39 return res%mod; 40 } 41 42 void init() { //階乘預(yù)處理 43 f[0] = 1; 44 for(LL i = 1; i < N; ++i) 45 f[i] = f[i - 1] * i % mod; 46 } 47 48 int main() 49 { 50 init(); 51 int t; 52 LL n, m, k; 53 scanf("%d", &t); 54 for(int ca = 1; ca <= t; ++ca) { 55 scanf("%lld %lld %lld", &n, &m, &k); 56 printf("Case #%d: ", ca); 57 if(k == 1 && n == 1) { 58 printf("%lld\n", m); 59 continue; 60 } 61 else if(k == 1) { 62 printf("0\n"); 63 continue; 64 } 65 LL ans = 0, temp = k; 66 for(int i = 1; k >= 2; --k, i = -i) { 67 ans = (i * Cnm(temp, k, mod) % mod *k % mod* Pow(k- 1, n - 1, mod) % mod + ans) % mod; 68 } 69 ans = ans * Cnm(m, temp, mod) % mod; 70 printf("%lld\n", (ans + mod) % mod); 71 } 72 return 0; 73 } View Code之前糾結(jié)了好久...
轉(zhuǎn)載于:https://www.cnblogs.com/Recoder/p/5773486.html
總結(jié)
以上是生活随笔為你收集整理的Codeforces 100548F - Color (组合数+容斥)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 微粒贷绑定的手机号怎么改
- 下一篇: 新生儿出生多久可以买保险