守卫者的挑战

     开始就想到了用一个三维的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 }

 

转载于:https://www.cnblogs.com/FOXYY/p/7241927.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值