守卫者的挑战

     开始就想到了用一个三维的f数组表示第i场,赢了几场,还剩下多少空间,但是发现空间的极限最大值是200000,在开一个三维的数组就爆内存了,后来想到用map实现动态开点,但是这样时间复杂度过不了,并且还表示不了赢了多少场的状态,后来参考了一下题解,发现当背包的空间加到大于n的时候,无论怎么样,背包空间的大小都不可能变为零,所以就可以把空间大于n的一起放到n上,以为在转移的时候,空间大小为负数依然合法,因为在后来可以通过扩大背包讲空间变为正的,处理的方法是将所有的空间大小都加上一个值,这要就能保证数组下标都是正的;

   开始还理解错题意了,以为胜利L场,并且背包空间非负就可以结束挑战,卡了很长时间,审题的重要性

 1 #include<map>
 2 #include<cmath>
 3 #include<ctime>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstdlib>
 7 #include<cstring>
 8 #include<iostream>
 9 #include<algorithm>
10 using namespace std;
11 int n,L,K;
12 double p[210];
13 int a[210];
14 double f[201][201][410];
15 int main(){
16     //freopen("a.in","r",stdin); //freopen("sc2.out","w",stdout);
17     //freopen("guarda.in","r",stdin); freopen("guarda.out","w",stdout);
18     scanf("%d%d%d",&n,&L,&K);
19     for(int i=1;i<=n;i++) scanf("%lf",&p[i]),p[i]/=100;
20     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
21     if(a[1]==-1){
22         f[1][1][K-1+205]=p[1];
23         f[1][0][K+205]=(1-p[1]);
24     }
25     else{
26         int cc=a[1]+K;
27         if(cc>n) cc=n;
28         f[1][1][cc+205]=p[1];
29         f[1][0][K+205]=(1-p[1]);
30     }
31     int N=n+205;
32     for(int i=2;i<=n;i++){
33         for(int j=0;j<=n;j++){
34             for(int k=1;k<=409;k++){
35                 if( f[i-1][j][k]==0 ) continue;
36                 if( a[i]==-1 ){
37                     f[i][j+1][k-1]+=f[i-1][j][k]*p[i];
38                     f[i][j][k]+=f[i-1][j][k]*(1-p[i]);
39                 }
40                 else{
41                     int d=a[i]+k;
42                     if(d>N) d=N;
43                     f[i][j+1][d]+=f[i-1][j][k]*p[i];
44                     f[i][j][k]+=f[i-1][j][k]*(1-p[i]);
45                     
46                 }
47             }
48         }
49     }
50     double ans=0;
51     for(int j=L;j<=n;j++){
52         for(int k=205;k<=409;k++){
53             ans+=f[n][j][k];
54         }
55     }
56     printf("%.6lf",ans);
57     return 0;
58     
59 }

 

posted @ 2017-07-26 20:59  Nawox  阅读(185)  评论(0编辑  收藏  举报