隐藏
「codevs1997」守卫者的挑战 - 动态规划 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「codevs1997」守卫者的挑战 - 动态规划

题目大意

瞬间,队员们被传送到了一个擂台上,最初身边有一个容量为$K$的包包。
擂台赛一共有$N$项挑战,各项挑战依次进行。第$i$项挑战有一个属性,如果$a_i\ge 0$,表示这次挑战成功后可以再获得一个容量为的包包;如果$a_i=-1$,则表示这次挑战成功后可以得到一个大小为$1$的地图残片。地图残片必须装在包包里才能带出擂台,包包没有必要全部装满,但是队员们必须把获得的所有的地图残片都带走(没有得到的不用考虑,只需要完成所有项挑战后背包容量足够容纳地图残片即可),才能拼出完整的地图。并且他们至少要挑战成功L次才能离开擂台。
队员们一筹莫展之时,善良的守卫者Nizem帮忙预估出了每项挑战成功的概率,其中第$i$项挑战成功的概率为$\frac{p_i}{100}$。现在,请你帮忙预测一下,队员们能够带上他们获得的地图残片离开擂台的概率。


题目分析

一道比较简单的概率Dp。
设$f[i,j,k]$为前$i$项任务成功$j$个,当前背包容量为$k$的概率。

讨论一下任务是否成功即可。


代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
struct Challenge {
double p;
int v;
bool operator < (const Challenge& b) const {
return v>b.v;
}
} a[205];
int n,m,K;
double f[205][205][205],ans=0;
int main() {
ios::sync_with_stdio(false);
cin>>n>>m>>K;
for(int i=1; i<=n; i++) {
cin>>a[i].p;
a[i].p/=100;
}
for(int i=1; i<=n; i++)cin>>a[i].v;
sort(a+1,a+n+1);
f[0][0][min(n,K)]=1;
for(int i=0; i<n; i++)
for(int j=0; j<=i; j++)
for(int k=0; k<=n; k++) {
f[i+1][j][k]+=f[i][j][k]*(1-a[i+1].p);
int tmp=min(k+a[i+1].v,n);
if(tmp<0)continue;
f[i+1][j+1][tmp]+=f[i][j][k]*a[i+1].p;
}
for(int i=m; i<=n; i++)
for(int j=0; j<=n; j++)
ans+=f[n][i][j];
printf("%0.6lf\n",ans);
return 0;
}
姥爷们赏瓶冰阔落吧~