题意: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 }