bzoj 3029 守卫者的挑战 —— 概率DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3029

设 f[i][j][k] 表示第 i 次挑战,已经成功 j 次,剩余容量为 k 的概率;

体积大于2000的按2001计算即可,反正也用不完,否则开不下。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=205,maxm=4005;
int n,l,m,a[maxn];
double p[maxn],f[maxn][maxm],ans;
int main()
{
    scanf("%d%d%d",&n,&l,&m);
    for(int i=1;i<=n;i++)scanf("%lf",&p[i]),p[i]/=100;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]>2000)a[i]=2001;
    }
    f[0][m+2000]=1;
    for(int i=1;i<=n;i++)
        for(int j=i;j>=0;j--)
            for(int k=maxm-1;k>=0;k--)
            {
                f[j][k]=f[j][k]*(1.0-p[i]);
                if(j&&k>=a[i])f[j][k]+=f[j-1][k-a[i]]*p[i];
            }
    for(int j=l;j<=n;j++)
        for(int k=2000;k<=maxm;k++)ans+=f[j][k];
    printf("%.6lf\n",ans);
    return 0;
}

 

posted @ 2018-07-25 19:39  Zinn  阅读(137)  评论(0编辑  收藏  举报