★ZOJ 3380 Patchouli's Spell Cards 详细题解 (递推+组合数求方案数)
Time Limit:?7 Seconds ?????Memory Limit:?65536 KB
Patchouli Knowledge, the unmoving great library, is a magician who has settled down in the Scarlet Devil Mansion (紅魔館). Her specialty is elemental magic employing the seven elements fire, water, wood, metal, earth, sun, and moon. So she can cast different spell cards like?Water Sign "Princess Undine",?Moon Sign "Silent Selene"?and?Sun Sign "Royal Flare". In addition, she can combine the elements as well. So she can also cast high-level spell cards like?Metal & Water Sign "Mercury Poison"?and?Fire, Water, Wood, Metal & Earth Sign "Philosopher's Stones"?.
Assume that there are?m?different elements in total, each element has?n?different phase. Patchouli can use many different elements in a single spell card, as long as these elements have the same phases. The level of a spell card is determined by the number of different elements used in it. When Patchouli is going to have a fight, she will choose?m?different elements, each of which will have a random phase with the same probability. What's the probability that she can cast a spell card of which the level is no less than?l, namely a spell card using at least?l?different elements.
Input
There are multiple cases. Each case contains three integers 1 ≤?m,?n,?l?≤ 100. Process to the end of file.
Output
For each case, output the probability as irreducible fraction. If it is impossible, output "mukyu~" instead.
Sample Input
7 6 5 7 7 7 7 8 9Sample Output
187/15552 1/117649 mukyu~ 跟:http://blog.csdn.net/qq_34374664/article/details/65935929對比理解下?題目意思:有m個位置,每個位置填入一個數,數的范圍是1~n,問至少有L個位置的數一樣的概率
?輸出要是最簡分數的形式,所以用大數JAVA
大致思路:
首先如果考慮有L, L + 1, .... m個位置上是一樣的方案數不好考慮, 但是可以從反面考慮, 計算只有1, 2, ... L - 1個位置有相同元素的方案數, 用總方案數n^m減去即可
如果用dp[i][j]表示用前i種元素填了j個位置(不一定是前j個), 且每個元素都沒有使用達到L個, 的方案數的話有
dp[i][j] = sigma(dp[i - 1][j - k]*C[m - (j - k)][k]) (0 <= k <= min(m, l))
那么最后的答案就是 (n^m-dp[1~n][m])/(n^m)
即用前i個元素填充j個位置的方案數相當于前i - 1個元素填充了j - k個位置, 第i個元素要填充k個位置, 這k個位置可以來自于剩下的m - (j - k)個位置中的其中k個
那么不滿足題意的方案總數是 sigma(dp[i][m]) (1 <= i <= n) 用所有可能的排列方案減去即可得到可行的方案數.
初始化dp[0][0] = 1, 其他值為0即可,這樣有些不符合的情況自動變成0了
很明顯只有當l > m時才會沒有可能的方案
考慮到計算時數據很大, 使用java方便一些
講道理 java真的是勁啊。。。? import java.math.BigInteger; import java.util.BitSet; import java.util.Scanner;public class Main {static BigInteger[][] dp = new BigInteger[110][110];static BigInteger[][] c = new BigInteger[110][110];public static void main(String[] args){Scanner sc = new Scanner(System.in);for(int i = 0; i < 105; i++){c[i][0] = c[i][i] = BigInteger.valueOf(1);for(int j = 1; j < i; j++)c[i][j] = c[i-1][j-1].add(c[i-1][j]);}int n, m, l;while(sc.hasNext()){m = sc.nextInt();n = sc.nextInt();l = sc.nextInt();BigInteger tot = BigInteger.valueOf(n).pow(m);if(l > m){System.out.println("mukyu~");continue;} // if(l>m/2)//這個時候可以直接用組合數求出來 // { // BigInteger ans=BigInteger.ZERO; // for(int i=l;i<=m;i++) // ans=ans.add(c[m][i].multiply(BigInteger.valueOf(n-1).pow(m-i))); // ans=ans.multiply(BigInteger.valueOf(n)); // BigInteger gcd=ans.gcd(tot); // System.out.println(ans.divide(gcd)+"/"+tot.divide(gcd)); // continue; // }for(int i = 0; i <= n; i++)for(int j = 0; j <= m; j++)dp[i][j] = BigInteger.valueOf(0);dp[0][0] = BigInteger.ONE; //0個元素房0個位置的概率肯定是1 啊for(int i = 1; i <= n; i++) //n個元素for(int j = 1; j <= m; j++) //j個位置,不一定連續for(int k = 0; k < l && k <= j; k++) //代表第i個元素不放,房1個,放兩個。。。最多放k個dp[i][j] = dp[i][j].add(dp[i-1][j-k].multiply(c[m-(j-k)][k])); // System.out.println(c[4][2]);BigInteger ans = BigInteger.ZERO;for(int i = 1; i <= n; i++)ans = ans.add(dp[i][m]);ans = tot.subtract(ans);BigInteger gcd = ans.gcd(tot);System.out.println(ans.divide(gcd)+"/"+tot.divide(gcd));}} }
總結
以上是生活随笔為你收集整理的★ZOJ 3380 Patchouli's Spell Cards 详细题解 (递推+组合数求方案数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过docker搭建lamp+wordp
- 下一篇: Android 手势拦截的实现(简化水平