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

 

 

 

你可能感兴趣的:(SPEL)