[HNOI2015]亚瑟王
首先可以知道的是,牌与牌之间的期望收益互相不影响,所以我们对每种牌分开进行计算。所以我们设出状态, 到第 种牌,已经过了 轮,第 种牌抽到的概率。
if(j) f[i][j]=(f[i-1][j-1]*(1.0-pow(1-a[i],r-j+1))+f[i][j]);
f[i][j]=(f[i-1][j]*pow(1-a[i],r-j)+f[i][j]);
第一行的意思是在后来的 轮中必有一次选到的概率是 。
第二行就是在后来的这些轮里一次都选不上,这时的概率是 。
最后的结果就是 。
到 时没被开到,后来有 的概率也开不到,那么当下被开到的概率就是乘积,再乘上收益就行。
#include <bits/stdc++.h>
using namespace std;
typedef double db;
const int maxn=320;
int T;
int n,r;
db a[maxn],f[maxn][maxn],ans;int d[maxn];
void clear()
{
memset(f,0,sizeof(f)); ans=0;
}
int main()
{
//freopen("p.in","r",stdin);
scanf("%d",&T);
while(T--)
{
clear();
scanf("%d%d",&n,&r);
for(int i=1;i<=n;i++)
{
scanf("%lf%d",&a[i],&d[i]);
}
f[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=min(i,r);j++)
{
if(j) f[i][j]=(f[i-1][j-1]*(1.0-pow(1-a[i],r-j+1))+f[i][j]);
f[i][j]=(f[i-1][j]*pow(1-a[i],r-j)+f[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<min(i,r);j++)
ans+=d[i]*f[i-1][j]*(1.0-pow(1-a[i],r-j));
}
printf("%.10f\n",ans);
}
}
本文作者:cc0000
本文链接:https://www.cnblogs.com/cc0000/p/16808153.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步