AcWing232 守卫者的挑战(数学+dp)
这题很容易想到转移方程式,问题是我们发现第三维如果开2000,会炸
但是我们进一步发现,没必要开2000,因为总共就200个任务,所以背包容量和减少的量的差值最多-200-200
然后平移一下就是0-400.之后就是dfs转移,另外,double类型不要用memset转移
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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))); }
没有人不辛苦,只有人不喊疼