洛谷 P3239 [HNOI2015]亚瑟王(期望dp)

本文深入探讨了一道涉及复杂期望动态规划(DP)的题目,通过详细解释算法思路,包括如何计算每张牌打出的概率,以及如何利用这些概率求解最终答案,为读者提供了清晰的解题路径。

题面

luogu

题解

一道复杂的期望\(dp\)

思路来源:__stdcall

容易想到,只要把每张牌打出的概率算出来就可以求出\(ans\)

\(fp[i]\)表示把第\(i\)张牌打出来的概率

可知:\(fp[0] = 1-(1-p[0])^r\)
\((1-p[0])^r\)即一直不打出的概率)

后面的\(fp\)怎么求?

\(f[i][j]\)表示前\(i\)张牌一共出了\(j\)张的概率, 那么就会有

\(fp[i] = \sum_{j=0}^{r}f[i-1][j]*(1-(1-p[i])^{r-j})\)
\(1−(1−p[i])^{r−j}\)就是在\(r−j\)轮中使用过第\(i\)张牌的概率)

那么问题只有如何求\(f\)

对于第\(i\)张牌,只有两种情况:
1.使用
\(f[i][j] += f[i-1][j-1]*(1-(1-p[i])^{r-j+1})\)

2.不使用
\(f[i][j] += f[i-1][j]*(1-p[i])^{r-j}\)

具体看代码。。
看完题解还是很容易的。。

Code

#include<bits/stdc++.h>

#define LL long long
#define RG register

using namespace std;
template<class T> inline void read(T &x) {
    x = 0; RG char c = getchar(); bool f = 0;
    while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    x = f ? -x : x;
    return ;
}
template<class T> inline void write(T x) {
    if (!x) {putchar(48);return ;}
    if (x < 0) x = -x, putchar('-');
    int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
}

const int N = 230;

double p[N], fp[N], P[N][N], f[N][N];
int d[N], n, r;
void pre() {
    for (int i = 1; i <= n; i++) {
        P[i][0] = 1;
        for (int j = 1; j <= r; j++)
            P[i][j] = P[i][j-1]*(1-p[i]);
    }
    return ;
}

void solve() {
    read(n); read(r);
    for (int i = 1; i <= n; i++)
        scanf("%lf", &p[i]), read(d[i]);
    pre();
    memset(f, 0, sizeof(f));
    memset(fp, 0, sizeof(fp));
    f[1][0] = P[1][r];
    f[1][1] = fp[1] = 1-f[1][0];
    for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= r; j++) {
            f[i][j] += f[i-1][j]*P[i][r-j];
            if (j) f[i][j] += f[i-1][j-1]*(1-P[i][r-j+1]);
        }
    }
    for (int i = 2; i <= n; i++)
        for (int j = 0; j <= r; j++)
            fp[i] += f[i-1][j]*(1-P[i][r-j]);
    double ans = 0;
    for (int i = 1; i <= n; i++)
        ans += fp[i]*d[i];
    printf("%lf\n", ans);
    return ;
}

int main() {
    int T; read(T);
    while (T--) solve();
    return 0;
}

转载于:https://www.cnblogs.com/zzy2005/p/10248844.html

根据引用\[1\]和引用\[2\]的描述,题目中的影魔拥有n个灵魂,每个灵魂有一个战斗力ki。对于任意一对灵魂对i,j (i<j),如果不存在ks (i<s<j)大于ki或者kj,则会为影魔提供p1的攻击力。另一种情况是,如果存在一个位置k,满足ki<c<kj或者kj<c<ki,则会为影魔提供p2的攻击力。其他情况下的灵魂对不会为影魔提供攻击力。 根据引用\[3\]的描述,我们可以从左到右进行枚举。对于情况1,当扫到r\[i\]时,更新l\[i\]的贡献。对于情况2.1,当扫到l\[i\]时,更新区间\[i+1,r\[i\]-1\]的贡献。对于情况2.2,当扫到r\[i\]时,更新区间\[l\[i\]+1,i-1\]的贡献。 因此,对于给定的区间\[l,r\],我们可以根据上述方法计算出区间内所有下标二元组i,j (l<=i<j<=r)的贡献之和。 #### 引用[.reference_title] - *1* *3* [P3722 [AH2017/HNOI2017]影魔(树状数组)](https://blog.youkuaiyun.com/li_wen_zhuo/article/details/115446022)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [3722 AH2017/HNOI2017 影魔 线段树 单调栈](https://blog.youkuaiyun.com/forever_shi/article/details/119649910)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值