Acwing 232. 守卫者的挑战

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Acwing 232. 守卫者的挑战相关的知识,希望对你有一定的参考价值。

Acwing 232. 守卫者的挑战

题意:

有n个挑战,一开始背包容量为k,每次挑战有p[i]的概率成功,成功的话会得到一个大小为1的地图碎片或者是提升背包容量X,所有的地图碎片必须装在包里,问最后带地图离开的概率

题解:

设f(i,j,k)表示前i个挑战赢了j次,剩余k次的概率
这么开数组的话会爆炸(200 * 200 * 2000),但是我们知道n个挑战也就最多只有x个地图碎片可以拿,那么只要容量大于n就必然成功。所以记f(i,j,n)表示前i个挑战赢了j次,剩余容量等于n的概率,既然是剩余空间,值域为[-200,200],数组加一个偏移量。这样就压缩到O(n3),就过了。

代码:

#include<bits/stdc++.h>
#define MAXN 205
using namespace std;
typedef long long ll;
int n,L,k;
double f[MAXN][MAXN][MAXN<<1|1],p[MAXN];
int main()
{
    cin>>n>>L>>k;
    if(k>n)k=n;
    double ans=0;
    f[0][0][n+k]=1;
    for(int i=1;i<=n;++i)scanf("%lf",&p[i]),p[i]/=100;
    for(int i=1;i<=n;++i)
    {
        int x;
        cin>>x;
        for(int j=0;j<i;++j)
            for(int k=0;k<=n+n;++k)
                if(k+x>=0)
                    f[i][j+1][min(n+n,k+x)]+=p[i]*f[i-1][j][k],f[i][j][k]+=(1-p[i])*f[i-1][j][k];
    }
    for(int j=L;j<=n;++j)
        for(int k=n;k<=(MAXN<<1);++k)ans+=f[n][j][k];
    printf("%.6lf",ans);
    return 0;
}

以上是关于Acwing 232. 守卫者的挑战的主要内容,如果未能解决你的问题,请参考以下文章

1997 守卫者的挑战

BZOJ3029守卫者的挑战 [期望DP]

TYVJ-P1864 守卫者的挑战 题解

BZOJ-3029: 守卫者的挑战 (期望DP)

TYVJ1864[Poetize I]守卫者的挑战 概率与期望

1997 守卫者的挑战