AcWing232 守卫者的挑战(数学+dp)

这题很容易想到转移方程式,问题是我们发现第三维如果开2000,会炸

但是我们进一步发现,没必要开2000,因为总共就200个任务,所以背包容量和减少的量的差值最多-200-200

然后平移一下就是0-400.之后就是dfs转移,另外,double类型不要用memset转移

#include<bits/stdc++.h>
using namespace std;
double f[205][205][410];
double p[210];
int a[205];
int l,n,k;
double dfs(int u,int x,int k){
    int i;
    if(u==n+1){
        if(x>=l&&k>=n)
        return 1;
        return 0;
    }
    if(f[u][x][k]!=-1)
    return f[u][x][k];
    double ans=0;
    if(a[u]!=-1){
        ans=p[u]*dfs(u+1,x+1,min(2*n,k+a[u]))+(1-p[u])*dfs(u+1,x,k);
    }
    else{
        ans=p[u]*dfs(u+1,x+1,k-1)+(1-p[u])*dfs(u+1,x,k);
    }
    return f[u][x][k]=ans;
}
int main(){
    cin>>n>>l>>k;
    int i,j,s;
    for(i=0;i<=n;i++){
        for(j=0;j<=n;j++){
            for(s=0;s<=2*n;s++)
            f[i][j][s]=-1;
        }
    }
    for(i=1;i<=n;i++){
        cin>>p[i];
        p[i]/=100;
    }
    for(i=1;i<=n;i++){
        cin>>a[i];
    }
    printf("%.6f\n",dfs(1,0,n+min(n,k)));
}
View Code

 

posted @ 2020-04-15 22:17  朝暮不思  阅读(130)  评论(0编辑  收藏  举报