思路:
dp[i]表示当前在已经投掷出i个不相同/相同这个状态时期望还需要投掷多少次
对于第一种情况有:
dp[0] = 1+dp[1]
dp[1] = 1+((m-1)*dp[1]+dp[2])/m
dp[i] = 1+((m-1)*dp[1]+dp[i+1])/m
……
dp[n] = 0
可以得到:dp[n-1]=m*dp[n]+1
所以dp[0]=(m^n-1)/(m-1)也即是第一种的答案!
对于第二种情况有:
dp[0]=1+dp[1]
dp[1]=1+(dp[1]+(m-1)*dp[2])/m
dp[i]=1+(dp[1]+……+dp[i]+(m-i)*dp[i+1])/m
……
dp[n]=0
令d[i]=dp[i]-dp[i+1]
则有d[i]=m*dp[i-1]/(m-i),d[0]=1
所以dp[0]=∑d[i]也即是第二种的答案!!
代码如下:
1 #include<stdio.h> 2 #include<cmath> 3 double sum,d; 4 int pows(int a,int b){ 5 int ans=1; 6 while(b){ 7 if(b&1) ans*=a; 8 b>>=1; 9 a*=a; 10 } 11 return ans; 12 } 13 int main(){ 14 int q,n,m,i,j,t; 15 while(scanf("%d",&t)!=EOF){ 16 for(i=0;i<t;i++){ 17 scanf("%d%d%d",&q,&m,&n); 18 if(q==0) printf("%.9lf ",(pows(m,n)-1.0)/(m-1.0)); 19 else{ 20 sum=d=1.0; 21 for(j=1;j<n;j++){ 22 d=1.0*m/(m-j)*d; 23 sum+=d; 24 } 25 printf("%.9lf ",sum); 26 } 27 } 28 } 29 return 0; 30 }