[HDU4652]Dice

vjudge

题意

\(m\)面骰子,求
1.连续出现\(n\)个相同的停止;
2.连续出现\(n\)个不同的停止
的期望投骰子次数。
\(n,m ≤ 10^6\)

sol

首先考虑一个转移式子吧。
\(f_i,g_i\)分别表示已经连续出现了\(i\)个相同/不同时的期望步数:
\[f_i=\frac 1mf_{i+1}+\frac{m-1}mf_1+1\]
(只有\(\frac 1m\)的概率继续投出对应的颜色,否则就前功尽弃,从\(1\)重新开始)
\[g_i=\frac{m-i}{m}g_{i+1}+\frac 1m\sum_{x=1}^{i}g_x+1\]
(如果投出了与之前相同的颜色,每种颜色各有\(\frac 1m\)的概率出现,所以各有\(\frac 1m\)的概率退回到\(1..i\)的状态)

边界状态\(f_n=g_n=0\),我们的目标是求\(f_0,g_0\)
考虑怎么解上面那个东西吧,这里我们用一种很经典的方法——错位相减

先做\(f_i\)吧。
\(f_{i+1}\)对应的式子写出来:
\[f_{i+1}=\frac 1mf_{i+2}+\frac{m-1}mf_1+1\]
两式相减:
\[f_i-f_{i+1}=\frac 1m(f_{i+1}-f_{i+2})\]
因为有一个很显然的条件式:\(f_0-f_1=1\)
所以就可以直接推得:
\(f_1-f_2=m,f_2-f_3=m^2......f_{n-1}-f_n=m^{n-1}\)
那么\(f_0=\sum_{i=0}^{n-1}m^i=\frac{1-m^n}{1-m}\)

然后是\(g_i\)
同样把\(g_{i+1}\)对应的式子写出来:
\[g_{i+1}=\frac{m-i-1}{m}g_{i+2}+\frac 1m\sum_{x=1}^{i+1}g_x+1\]
同样两式相减:
\[g_i-g_{i+1}=\frac{m-i}mg_{i+1}-\frac{m-i-1}mg_{i+2}-\frac 1mg_{i+1}\\=\frac{m-i-1}m(g_{i+1}-g_{i+2})\]
同样还是根据\(g_0-g_1=1\)的性质可知:
\(g_1-g_2=\frac m{m-1},g_2-g_3=\frac{m^2}{(m-1)(m-2)}......\)
线性递推即可。
时间复杂度\(O(Tn)\)

code

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
    int T;
    while (scanf("%d",&T)!=EOF)
        while (T--)
        {
            int ty,m,n;scanf("%d%d%d",&ty,&m,&n);
            if (!ty)
                printf("%.10lf\n",(pow(m,n)-1)/(m-1));
            else
            {
                double ans=0,last=1;
                for (int i=1;i<=n;++i)
                    ans+=last,last*=1.0*m/(m-i);
                printf("%.10lf\n",ans);
            }
        }
    return 0;
}

转载于:https://www.cnblogs.com/zhoushuyu/p/8669098.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值