/*
hdu 4652
题目大意是
有一个m个面的骰子
然后根据输入求
连续出现n个相同面
以及n个不同面的期望
以往的概率dp都是考虑
dp[i]由什么组成,然后列出递推方程
而这题考虑,dp[i]会变化成什么
1.连续出现n个相同面的期望
设dp[n]表示已经掷出n个相同的面的期望
那么
dp[0]=dp[1]+1,dp[0]=1(出现0个相同面的概率为1)
因为0之后一定变成1
dp[1]=1/m*dp[2]+(m-1)/m*dp[1]+1
因为接下来可能继续出现开始出现的这个数
所以继续出现这个数的概率为1/m
不出现这个数就会又变成1,概率就为(m-1)/m
所以可得递推公式为
dp[n]=1/m*dp[n+1]+(m-1)/m*dp[1]+1
变换一下可得
dp[n+1]=m*dp[n]-(m-1)*dp[1]-m
dp[n]=m*dp[n-1]-(m-1)*dp[1]-m
dp[n-1]=m*dp[n-2]-(m-1)*dp[1]-m
dp[n]-dp[n-1]=m*(dp[n-1]-dp[n-2])
迭代后得
dp[n]-dp[n-1]=m^n
dp[n-1]-dp[n-2]=m^(n-1)
:
:
dp[1]-dp[0]=m
累加后得
dp[n]-dp[0]=m^n+m^(n-1)+……+m
dp[n]=m^n+m^(n-1)+……+m+1
2.连续n个不同面的期望
其思路与1大体类似
设dp[n]表示已经掷出n个不同相同的面的期望
那么
dp[0]=dp[1]+1,dp[0]=0(出现0个不同面的概率为0)
因为0的后继状态只有1这一种概率为1,所以
dp[1]=(m-1)/m*dp[2]+1/m*dp[1]+1
同理,因为1的后继状态有1,2,这两种情况概率为1/m,(m-1)/m,所以
dp[2]=(m-2)/m*dp[3]+1/m*(dp[1]+dp[2])+1
以此类推
dp[n-1]=(m-n+1)/m*dp[n]+1/m*(dp[1]+dp[2]+……+dp[n-1])+1
dp[n]=(m-n)/m*dp[n+1]+1/m*(dp[1]+dp[2]+……+dp[n])+1
dp[n]-dp[n-1]=(m-n)/m*(dp[n+1]-dp[n])
dp[n+1]-dp[n]=m/(m-n)*(dp[n]-dp[n-1])
dp[n]-dp[n-1]=m/(m-n+1)*(dp[n-1]-dp[n-2])
迭代后得
dp[n]-dp[n-1]=m/(m-n+1)*m/(m-n+2)*……*m/(m-1)*m/m
最后有
dp[n]-dp[n-1]=m/(m-n+1)*m/(m-n+2)*……*m/(m-1)
dp[n-1]-dp[n-2]=m/(m-n+2)*m/(m-n+3)*……*m/(m-1)
:
:
dp[1]-dp[0]=1
累加后有
dp[n]-dp[0]=(m/(m-n+1)*m/(m-n+2)*……*m/(m-1))+(m/(m-n+2)*m/(m-n+3)*……*m/(m-1))+……+1
dp[n]=(m/(m-n+1)*m/(m-n+2)*……*m/(m-1))+(m/(m-n+2)*m/(m-n+3)*……*m/(m-1))+……+1
*/
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define mod 1000000007
#define MAX 100005
#define ll long long
#define PI acos(-1)
using namespace std;
int main()
{
int t;
while(cin>>t)
{
while(t--)
{
int flag,m,n;
cin>>flag>>m>>n;
double ans=1.0;
if(flag)
{
double sum=1.0;
for(int i=1;i<=n-1;i++)
{
sum=sum*m*1.0/(m-i);
ans=ans+sum;
}
}
else
{
double tmp=(double)m;
for(int i=1;i<=n-1;i++)
{
ans=ans+tmp;
tmp=tmp*(double)m;
}
}
printf("%.9lf\n",ans);
}
}
return 0;
}
hdu 4652
题目大意是
有一个m个面的骰子
然后根据输入求
连续出现n个相同面
以及n个不同面的期望
以往的概率dp都是考虑
dp[i]由什么组成,然后列出递推方程
而这题考虑,dp[i]会变化成什么
1.连续出现n个相同面的期望
设dp[n]表示已经掷出n个相同的面的期望
那么
dp[0]=dp[1]+1,dp[0]=1(出现0个相同面的概率为1)
因为0之后一定变成1
dp[1]=1/m*dp[2]+(m-1)/m*dp[1]+1
因为接下来可能继续出现开始出现的这个数
所以继续出现这个数的概率为1/m
不出现这个数就会又变成1,概率就为(m-1)/m
所以可得递推公式为
dp[n]=1/m*dp[n+1]+(m-1)/m*dp[1]+1
变换一下可得
dp[n+1]=m*dp[n]-(m-1)*dp[1]-m
dp[n]=m*dp[n-1]-(m-1)*dp[1]-m
dp[n-1]=m*dp[n-2]-(m-1)*dp[1]-m
dp[n]-dp[n-1]=m*(dp[n-1]-dp[n-2])
迭代后得
dp[n]-dp[n-1]=m^n
dp[n-1]-dp[n-2]=m^(n-1)
:
:
dp[1]-dp[0]=m
累加后得
dp[n]-dp[0]=m^n+m^(n-1)+……+m
dp[n]=m^n+m^(n-1)+……+m+1
2.连续n个不同面的期望
其思路与1大体类似
设dp[n]表示已经掷出n个不同相同的面的期望
那么
dp[0]=dp[1]+1,dp[0]=0(出现0个不同面的概率为0)
因为0的后继状态只有1这一种概率为1,所以
dp[1]=(m-1)/m*dp[2]+1/m*dp[1]+1
同理,因为1的后继状态有1,2,这两种情况概率为1/m,(m-1)/m,所以
dp[2]=(m-2)/m*dp[3]+1/m*(dp[1]+dp[2])+1
以此类推
dp[n-1]=(m-n+1)/m*dp[n]+1/m*(dp[1]+dp[2]+……+dp[n-1])+1
dp[n]=(m-n)/m*dp[n+1]+1/m*(dp[1]+dp[2]+……+dp[n])+1
dp[n]-dp[n-1]=(m-n)/m*(dp[n+1]-dp[n])
dp[n+1]-dp[n]=m/(m-n)*(dp[n]-dp[n-1])
dp[n]-dp[n-1]=m/(m-n+1)*(dp[n-1]-dp[n-2])
迭代后得
dp[n]-dp[n-1]=m/(m-n+1)*m/(m-n+2)*……*m/(m-1)*m/m
最后有
dp[n]-dp[n-1]=m/(m-n+1)*m/(m-n+2)*……*m/(m-1)
dp[n-1]-dp[n-2]=m/(m-n+2)*m/(m-n+3)*……*m/(m-1)
:
:
dp[1]-dp[0]=1
累加后有
dp[n]-dp[0]=(m/(m-n+1)*m/(m-n+2)*……*m/(m-1))+(m/(m-n+2)*m/(m-n+3)*……*m/(m-1))+……+1
dp[n]=(m/(m-n+1)*m/(m-n+2)*……*m/(m-1))+(m/(m-n+2)*m/(m-n+3)*……*m/(m-1))+……+1
*/
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define mod 1000000007
#define MAX 100005
#define ll long long
#define PI acos(-1)
using namespace std;
int main()
{
int t;
while(cin>>t)
{
while(t--)
{
int flag,m,n;
cin>>flag>>m>>n;
double ans=1.0;
if(flag)
{
double sum=1.0;
for(int i=1;i<=n-1;i++)
{
sum=sum*m*1.0/(m-i);
ans=ans+sum;
}
}
else
{
double tmp=(double)m;
for(int i=1;i<=n-1;i++)
{
ans=ans+tmp;
tmp=tmp*(double)m;
}
}
printf("%.9lf\n",ans);
}
}
return 0;
}