ZOJ-3380 Patchouli's Spell Cards(概率DP大数)
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~References
題目大意:有m種不同的元素,每個元素有n種不同的階段,只有處于相同階段的元素才能放入咒語中,求一個咒語中至少有l(wèi)種不同的元素的概率?
題目大概直譯就是這樣,但是完全沒有思路
看了題解后發(fā)現大神總結抽象能力好強,抽象成:有m個位置,在每個位置隨機填上1~n個數,求相同的數至少有l(wèi)的概率?
即使這樣還是沒有思路,認為是容斥什么的直接計算,完全想不到概率DP
大致思路如下:正難則反,統(tǒng)計填滿數后相同的數小于l的情況
設dp[i][j]表示前i個數占據j個位置的方案數(且每個數占據的位置小于l)
該狀態(tài)可由前i-1個數占據max(j-l+1,0) ~ j個位置轉移而來,保證第i個數占據的位置數小于l
則狀態(tài)轉移方程為:dp[i][j]=∑dp[i-1][j-k]*c(m-j+k,k) (k<=j&&k<l)
則∑dp[i][m] 表示用i個數填滿后,每個數出現次數都小于ll時的方案數
則n^m-∑dp[i][m] 為相同的數至少有l(wèi)的的方案數
import java.util.*; import java.math.*;public class Main {static BigInteger[][] dp=new BigInteger[105][105];static BigInteger[][] c=new BigInteger[105][105];static BigInteger fact,deno,gcd;public static void main(String[] argv) {for(int i=0;i<=100;++i) {c[i][0]=c[i][i]=BigInteger.ONE;for(int j=1;j<i;++j) {c[i][j]=c[i-1][j-1].add(c[i-1][j]);//楊輝三角形計算組合數}}Scanner cin=new Scanner(System.in);int m,n,l;while(cin.hasNext()) {m=cin.nextInt();n=cin.nextInt();l=cin.nextInt();if(l>m) {System.out.println("mukyu~");}else if(l>m/2) {//如果至少需要的階段相同的元素超過一半,則必定只有一種相同的階段fact=BigInteger.ZERO;deno=BigInteger.valueOf(n).pow(m);//合法的總方案數for(int i=l;i<=m;++i) {//枚舉階段相同的元素個數fact=fact.add(c[m][i].multiply(BigInteger.valueOf(n-1).pow(m-i)));//從m個元素中選擇i個元素其階段相同,其余m-i個元素可在剩下的n-1個階段任選}fact=fact.multiply(BigInteger.valueOf(n));//不同元素的相同階段共有n種gcd=fact.gcd(deno);//分子分母的最大公約數System.out.println(fact.divide(gcd)+"/"+deno.divide(gcd));//輸出最簡分數}else {//存在多種相同的階段的元素個數都超過l時,進行DPfor(int i=0;i<=n;++i) {for(int j=0;j<=m;++j) {dp[i][j]=BigInteger.ZERO;}}dp[0][0]=BigInteger.ONE;for(int i=1;i<=n;++i) {//枚舉階段for(int j=1;j<=m;++j) {//枚舉元素for(int k=0;k<l&&k<=j;++k) {//枚舉階段相同的元素dp[i][j]=dp[i][j].add(dp[i-1][j-k].multiply(c[m-j+k][k]));}}}fact=BigInteger.ZERO;deno=BigInteger.valueOf(n).pow(m);//合法的總方案數for(int i=1;i<=n;++i) {fact=fact.add(dp[i][m]);}fact=deno.subtract(fact);gcd=fact.gcd(deno);//分子分母的最大公約數System.out.println(fact.divide(gcd)+"/"+deno.divide(gcd));//輸出最簡分數}}} }總結
以上是生活随笔為你收集整理的ZOJ-3380 Patchouli's Spell Cards(概率DP大数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于中科院力学所怀柔试验基地被非法拆毁的
- 下一篇: 变色龙哈希函数-区块链