题意: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 }
本文详细介绍了如何使用动态规划解决排列组合问题中的概率计算问题,通过构建状态转移方程和利用组合数学公式,实现对特定条件下相同元素出现次数的概率求解。文中提供了一个具体实例并给出相应的代码实现,旨在帮助读者理解和掌握此类问题的解决方法。
283

被折叠的 条评论
为什么被折叠?



