题目链接:
题意:m个位置,每个位置可以放n种数字(1-n)。问至少有L个位置数字一样的概率?
思路:反着想,我们先求出没有L个位置数字一样的放法ans。dp[i][j]表示前i种数字占据j个位置的放法数,dp[i][j]=sum(dp[i-1][j-k]*C[m-(j-k)][k])(k<L)。则ans=sum(dp[i][m])。则真正的答案Ans=n^m-ans。
import java.util.*;import java.math.*;public class Main{ static BigInteger dp[][]=new BigInteger[105][105]; static BigInteger C[][]=new BigInteger[105][105]; public static void puts(String s){ System.out.println(s); } public static void main(String[] args){ int i,j,k; BigInteger one=BigInteger.ONE,zero=BigInteger.ZERO; for(i=0;i<=100;i++){ C[i][0]=C[i][i]=one; for(j=1;j m) { puts("mukyu~"); continue; } for(i=0;i<=n;i++) for(j=0;j<=m;j++) dp[i][j]=zero; dp[0][0]=one; for(i=1;i<=n;i++) for(j=1;j<=m;j++) for(k=0;k<=j;k++) { dp[i][j]=dp[i][j].add(dp[i-1][j-k].multiply(C[m-(j-k)][k])); } BigInteger ans=zero; for(i=1;i<=n;i++) ans=ans.add(dp[i][m]); BigInteger tot=BigInteger.valueOf(n).pow(m); ans=tot.subtract(ans); BigInteger gcd=ans.gcd(tot); ans=ans.divide(gcd); tot=tot.divide(gcd); System.out.println(ans+"/"+tot); } }}