bzoj 3029 守卫者的挑战

水题,唯一值得提的是我们不用维护背包剩余空间为O(K)的情况,只要维护最大到n的情况就行了。因为只要剩余空间到了n,无论如何也不会装满。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>

#define md
#define ll long long
#define inf (int) 1e9
#define eps 1e-8
#define N 250
using namespace std;
double f[2][2*N][N];
double p[N];
int a[N];
int main()
{
int der=210;
int n,L,K;
scanf("%d%d%d",&n,&L,&K); f[0][K+der][0]=1;
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]);
for (int i=1;i<=n;i++)
{
bool fr,t;
fr=(i-1)&1; t=fr^1;
for (int j=der-n;j<=der+n+1;j++)
for (int k=0;k<=n;k++)
f[t][j][k]=0;
for (int j=der-n;j<=der+n+1;j++)
for (int k=0;k<=i;k++)
{
f[t][min(j+a[i],der+n+1)][k+1]+=f[fr][j][k]*p[i];
f[t][j][k]+=f[fr][j][k]*(1-p[i]);
}/*
for (int j=der-n;j<=der+n+1;j++)
{
if (j==der) printf("..."); else printf(" ");
for (int k=0;k<=i;k++)
printf("%.3lf ",f[t][j][k]);
printf("\n");
}
printf("\n");*/
}
double ans=0;
int i=n&1;
for (int j=der;j<=der+n+1;j++)
for (int k=L;k<=n;k++)
ans+=f[i][j][k];
printf("%.6lf\n",ans);
return 0;
}


你可能感兴趣的:(bzoj 3029 守卫者的挑战)