枚举所有的最大值盒子里糖果为K的情况,对于位置p,dp[p]为p以前的,第p个操作为抽到不是蓝球里的情况,盒子里最多糖果为k的情况的概率。而到p这个位置,可以有连续最多k-1(因为第k个操作必须为抽到不是蓝球,注意,在第一次操作前桌子上已有一粒糖)个,也可以是0,1,2,3,4....,所以维护这样的一段和,使它可以转移到第p个操作。
其实,我觉得应该把题解截下来:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; double dp[1550]; double power[1550]; double ans[1550]; double pre[1550]; int main(){ int T,n; double p,q; scanf("%d",&T); while(T--){ scanf("%d%lf%lf",&n,&p,&q); power[0]=1; double pro0=q/p; double pro1=(p-q)/p; for(int i=1;i<=n+1;i++){ power[i]=power[i-1]*pro0; } ans[0]=0; n++; for(int i=1;i<=n;i++){ dp[0]=pre[0]=1; for(int j=1;j<=n;j++){ double now=pre[j-1]; if(j-1-i>=0) now-=pre[j-1-i]*power[i]; dp[j]=now*pro1; pre[j]=pre[j-1]*pro0+dp[j]; } ans[i]=dp[n]; } double e=0; for(int i=n;i>=1;i--){ e+=(ans[i]-ans[i-1])*i; } e/=pro1; printf("%.3lf ",e); } return 0; }