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; }