Processing math: 100%
博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

HDU.5985.Lucky Coins(概率DP)

题目链接

Description

有n(n<=10)种硬币,已知每种硬币的数量和它抛一次正面朝上的概率pi。进行如下过程:每次抛一次所有硬币,将正面朝下的硬币去掉。重复该过程直到只剩一种硬币或是没有硬币。
如果结束时还剩下一种硬币,那称它是 LuckyCoin。求每种硬币成为 LuckyCoin 的概率。

Solution

我们只需要枚举在第j轮,硬币i死亡(这个词形象233),其它硬币在第j轮之前死亡的概率。
由给出的概率及六位小数可以看出,枚举到100轮就很够了。于是可以dp计算每种硬币在第j轮死亡的概率,然后前缀和一下,枚举轮数。(据说复杂度有点高?不太懂,不深究了...)
f[i][j] 表示在第j轮 硬币i死亡的概率,那么 f[i][j]=(1pji)numi (numi枚硬币都挂掉才死亡;算存活概率的话好像因为有多个很不好算)
g[i][j] 表示在第j轮之后 硬币i仍存活的概率,那么 g[i][j]=1f[i][j].
为了不重复统计(在第j+1轮i存活,但却计算在第j轮之前就死亡的所有硬币),对于每轮我们用i在j轮还存活,j+1轮i全部挂掉的概率,即 g[i][j]g[i][j+1].

Ans[i]=100j=1(g[i][j]g[i][j+1])nk=1,k!=if[k][j]

我想问为什么存下 g[i][j]=1f[i][j],计算用 g[][]就对,而不存直接用 1f[][]这个式子答案怎么需要+1。。(精度?)

//0MS 1564K
#include <cstdio>
#include <cctype>
#define gc() getchar()
const int N=12;

int n,num[N];
double p[N],f[N][103],g[N][103];

inline double FP(double x,int k)//第一次写double快速幂。。
{
	double t=1.0;
	for(; k; k>>=1,x=x*x) if(k&1) t=t*x;
	return t;
}

int main()
{
	int T; scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1; i<=n; ++i) scanf("%d%lf",&num[i],&p[i]);
		if(n==1) {puts("1.000000"); continue;}
		for(int i=1; i<=n; ++i)
		{
			double pw=p[i];
			for(int j=1; j<100; ++j,pw*=p[i]) f[i][j]=FP(1.0-pw,num[i]),g[i][j]=1-f[i][j];
		}
		for(int i=1; i<=n; ++i)
		{
			double res=0;
			for(int j=1; j<100; ++j)
			{
				double pro=1.0;
				for(int k=1; k<=n; ++k) if(k!=i) pro*=f[k][j];
				res += (f[i][j+1]-f[i][j])*pro;
//				res += (1-f[i][j]-1+f[i][j+1])*pro;
//				res += (g[i][j]-g[i][j+1])*pro;
			}
			printf("%f%c",res+1,i==n?'\n':' ');
		}
	}
	return 0;
}
posted @   SovietPower  阅读(222)  评论(0编辑  收藏  举报
编辑推荐:
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
阅读排行:
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率
· AI Agent爆火后,MCP协议为什么如此重要!
点击右上角即可分享
微信分享提示