【[HNOI2015]亞瑟王】
阿新 • • 發佈:2019-01-01
i++ efi clas 題解 eof set har [1] 就是 輪我們讓其不發動就好了
神仙題,抄題解
用\(tp_i\)表示\(i\)這個技能在\(r\)輪中被使用過的概率
於是最後的答案就是\(\sum_{i=1}^nd_i*tp_i\)
首先\(tp_1=1-(1-p_1)^r\),也就是連續\(r\)輪都沒有使用的概率
之後往下的\(tp\)靠\(dp\)來求
設\(dp_{i,j}\)表示在一共\(r\)輪裏,前\(i\)個恰好有\(j\)個被發動的概率
那麽
\[tp_i=1-\sum_{j=0}^rdp_{i-1,j}*(1-p_i)^{r-j}\]
還是先算一下這個技能一直都沒有發動的概率,如果前面有\(j\)個技能使用了,那麽那對應的輪次是一定不會使用當前技能的,剩下的輪次,也就是\(r-j\)
之後是\(dp_{i,j}\)的轉移
如果這一個技能並沒有發動,那麽就從\(dp_{i-1,j}\)轉移過來
\[dp_{i,j}=dp_{i-1,j}*(1-p_i)^{r-j}\]
如果這個技能發動了,那麽就需要從前面的\(dp_{i-1,j-1}\)轉移
\[dp_{i,j}=dp_{i-1,j-1}*(1-(1-p_i)^{r-j+1})\]
我們還是先令技能\(i\)不發動,那麽前面就會有\(r-j+1\)個輪次可能發動,我們都讓其不發動,之後拿\(1\)減掉,就是發動的概率了
代碼
#include<iostream> #include<cstring> #include<cstdio> #define re register #define maxn 225 #define min(a,b) ((a)<(b)?(a):(b)) double dp[maxn][maxn]; double p[maxn]; int d[maxn],n,T,m; double tp[maxn]; inline double quick(double a,int b) { double S=1.0; while(b) {if(b&1) S*=a;b>>=1,a*=a;} return S; } int main() { scanf("%d",&T); while(T--) { memset(dp,0,sizeof(dp)); memset(p,0,sizeof(p)); memset(tp,0,sizeof(tp)), memset(d,0,sizeof(d)); scanf("%d%d",&n,&m); for(re int i=1;i<=n;i++) scanf("%lf%d",&p[i],&d[i]); dp[1][0]=quick((1-p[1]),m); dp[1][1]=1-dp[1][0]; tp[1]=dp[1][1]; for(re int i=2;i<=n;i++) { for(re int j=0;j<=min(i-1,m);j++) tp[i]+=dp[i-1][j]*quick((1-p[i]),m-j); tp[i]=1-tp[i]; for(re int j=0;j<=min(i,m);j++) { dp[i][j]=dp[i-1][j]*quick((1-p[i]),m-j); if(j) dp[i][j]+=dp[i-1][j-1]*(1-quick((1-p[i]),m-j+1)); } } double ans=0; for(re int i=1;i<=n;i++) ans+=tp[i]*d[i]; printf("%.10lf",ans),putchar(10); } return 0; }
【[HNOI2015]亞瑟王】