有劳各位大佬帮忙看一下这道绿题的概率DP题我哪里出错了
查看原帖
有劳各位大佬帮忙看一下这道绿题的概率DP题我哪里出错了
291976
quanjun楼主2024/9/12 21:31

状态 fi,s,kf_{i, s, k} 表示:

  • 当前正面临第 ii 项挑战(此时第 1i11 \sim i-1 项挑战已完成,第 ii 项挑战还没开始);
  • 目前已经挑战成功了 ss 项(即第 1i11 \sim i-1 项挑战中共有 ss 项挑战成功,(i1)s(i-1)-s 项没挑战成功);
  • 此时的背包容量剩余 kk(实际实现时加了一个 210210 的偏移)。

边界条件时 i=n+1i = n+1,此时第 11i1=ni-1 = n 项挑战均已挑战完成。

此时若 sLs \ge L(至少挑战成功 LL 次) 且 k0k \ge 0(背包足够装所有的地图残片),则获胜的概率为 11;否则,获胜的概率为 00

非边界情况下:

fi,s,kf_{i, s, k}pip_i 的概率转移到 fi+1,s+1,k+aif_{i+1, s+1, k + a_i},有 1pi1 - p_i 的概率转移到 fi+1,s,kf_{i+1, s, k},所以:

fi,s,k=pi×fi+1,s+1,k+ai+(1pi)×fi+1,s,kf_{i, s, k} = p_i \times f_{i+1, s+1, k + a_i} + (1 - p_i) \times f_{i+1, s, k}

但是第 22 组样例就 WA 了,不知道哪里思考错了,这是我的代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 220;
bool vis[maxn][maxn][maxn*2];
double f[maxn][maxn][maxn*2];
int n, L, K, a[maxn];
double p[maxn];

// 当前在第 i 局,目前已经赢了 s 局,剩余背包容量为 k
double dfs(int i, int s, int k) {
    k = min(k, maxn*2-1);
    if (i == n+1) {
        return k >= 210 && s >= L ? 1 : 0;
    }
    if (vis[i][s][k])
        return f[i][s][k];
    vis[i][s][k] = true;
    return f[i][s][k] = p[i] * dfs(i+1, s+1, k + a[i]) + (1 - p[i]) * dfs(i+1, s, k);
}

int main() {
    cin >> n >> L >> K;
    for (int i = 1; i <= n; i++) {
        cin >> p[i];
        p[i] /= 100.0;
    }
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    double res = dfs(1, 0, 210);
    printf("%.6lf\n", res);
    return 0;
}

但是不知道哪里错了,有劳各位大佬帮忙看一下

2024/9/12 21:31
加载中...