zoj 3380 Patchouli's Spell Cards 概率DP

题意:1-n个位置中,每个位置填一个数,问至少有l个数是相同的概率。

可以转化求最多有l-1个数是相同的。

dp[i][j]表示前i个位置填充j个位置的方案数,并且要满足上面的条件。

则:

dp[i][j]=∑dp[i-1][j-k]*c[m-j+k][k];

也就是看第i个数,可以不填,填一个位置,两个位置······这样累加过来。

代码如下:

 1 import java.math.*;
 2 import java.util.*;
 3 public class Main {
 4     public static void main(String arg[]){
 5         BigInteger ans,sum,gcd;
 6         BigInteger c[][]=new BigInteger[101][101];
 7         int i,j,k,t,n,m,l;
 8         for(i=0;i<=100;i++){
 9             c[i][0]=BigInteger.ONE;
10             c[i][i]=BigInteger.ONE;
11         }
12         for(i=2;i<=100;i++)
13             for(j=1;j<i;j++)
14                 c[i][j]=c[i-1][j].add(c[i-1][j-1]);
15         Scanner cin = new Scanner(System.in);
16         while(cin.hasNext()){
17             m=cin.nextInt();
18             n=cin.nextInt();
19             l=cin.nextInt();
20             if(l>m){
21                 System.out.println("mukyu~");
22                 continue;
23             }
24             BigInteger dp[][]=new BigInteger[101][101];
25             for(i=0;i<=n;i++)
26                 for(j=0;j<=m;j++)
27                     dp[i][j]=BigInteger.ZERO;
28             dp[0][0]=BigInteger.ONE;
29             for(i=1;i<=n;i++)
30                 for(j=1;j<=m;j++){
31                     for(k=0;k<=j&&k<l;k++){
32                         dp[i][j]=dp[i][j].add(dp[i-1][j-k].multiply(c[m-j+k][k]));
33                     }
34                 }
35             ans=BigInteger.ZERO;
36             sum=BigInteger.valueOf(n).pow(m);
37             for(i=1;i<=n;i++){
38                 ans=ans.add(dp[i][m]);
39             }
40             ans=sum.subtract(ans);
41             gcd=ans.gcd(sum);
42             System.out.println(ans.divide(gcd)+"/"+sum.divide(gcd));                
43         }
44     }
45 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3254676.html