【题解】LuoGu3239:亚瑟王

原题传送门
p i p_i pi表示第 i i i个技能的概率
a n s = ∑ p i ∗ d i ans=\sum p_i*d_i ans=pidi

d p i , j dp_{i,j} dpi,j表示前 i i i个技能,成功了 j j j个的概率
d p i , j = d p i − 1 , j ∗ ( 1 − p i ) r − j + d p i − 1 , j − 1 ∗ [ 1 − ( 1 − p i ) r − j + 1 ] dp_{i,j}=dp_{i-1,j}*(1-p_i)^{r-j}+dp_{i-1,j-1}*[1-(1-p_i)^{r-j+1}] dpi,j=dpi1,j(1pi)rj+dpi1,j1[1(1pi)rj+1]
p i = ∑ d p i − 1 , j ∗ [ 1 − ( 1 − p i ) r − j ] p_i=\sum dp_{i-1,j}*[1-(1-p_i)^{r-j}] pi=dpi1,j[1(1pi)rj]

Code:

#include <bits/stdc++.h>
#define maxn 251
using namespace std;
double p[maxn], dp[maxn][maxn], power[maxn][maxn], d[maxn];
int n, m;

int main(){
	int T; scanf("%d", &T);
	while (T--){
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; ++i){
			scanf("%lf%lf", &p[i], &d[i]);
			power[i][0] = 1;
			for (int j = 1; j <= m; ++j) power[i][j] = power[i][j - 1] * (1 - p[i]);
		}
		dp[0][0] = 1;
		for (int i = 1; i <= n; ++i)
			for (int j = 0; j <= i; ++j){
				dp[i][j] = dp[i - 1][j] * power[i][m - j];
				if (j) dp[i][j] += dp[i - 1][j - 1] * (1 - power[i][m - j + 1]);
			}
		double ans = 0;
		for (int i = 1; i <= n; ++i){
			double s = 0;
			for (int j = 0; j <= i - 1; ++j) s += dp[i - 1][j] * (1 - power[i][m - j]);
			ans += s * d[i];
		}
		printf("%.10lf\n", ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值