题意
题解
d
p
[
i
+
1
]
[
j
]
[
k
]
dp[i+1][j][k]
dp[i+1][j][k] 代表在
0
⋯
i
0\cdots i
0⋯i 这
i
+
1
i+1
i+1 个挑战中,成功了
j
j
j 次,背包剩余容量为
k
k
k 的概率。显然,状态向前递推比较方便。根据挑战是否成功,得到
{
d
p
[
i
+
1
]
[
j
+
1
]
[
k
+
a
[
i
]
]
+
=
d
p
[
i
]
[
j
]
[
k
]
×
p
[
i
]
d
p
[
i
+
1
]
[
j
]
[
k
]
+
=
d
p
[
i
]
[
j
]
[
k
]
×
(
1
−
p
[
i
]
)
\begin{cases} dp[i+1][j+1][k+a[i]]+=dp[i][j][k]\times p[i]\\ dp[i+1][j][k]+=dp[i][j][k]\times (1-p[i])\\ \end{cases}
{dp[i+1][j+1][k+a[i]]+=dp[i][j][k]×p[i]dp[i+1][j][k]+=dp[i][j][k]×(1−p[i])
时空复杂度
O
(
N
2
∑
a
[
i
]
)
O(N^2\sum a[i])
O(N2∑a[i]),由于地图碎片贡献为
−
1
-1
−1,至多贡献
−
N
-N
−N,那么背包剩余容量大于等于
N
N
N 即能保证可以带上地图碎片离开擂台,
D
P
DP
DP 第三维规模缩小为
O
(
N
)
O(N)
O(N)即可。此时,时空复杂度降为
O
(
N
3
)
O(N^3)
O(N3)。
需要注意的是,能够带地图碎片离开擂台,只需要保证完成
N
N
N 项挑战后背包容量大于地图碎片总容量。那么递推过过程中需要考虑背包容量小于零的情况,为方便起见,将第三维值域修改为
[
−
N
,
N
]
⇒
[
0
,
2
N
]
[-N,N]\Rightarrow [0,2N]
[−N,N]⇒[0,2N]。答案为
∑
L
≤
j
≤
N
,
N
≤
k
≤
2
N
d
p
[
N
]
[
j
]
[
k
]
\sum\limits_{L\leq j\leq N,N\leq k\leq 2N}dp[N][j][k]
L≤j≤N,N≤k≤2N∑dp[N][j][k]
#include <bits/stdc++.h>
using namespace std;
const int maxn = 205;
int N, L, K, A[maxn];
double P[maxn], dp[maxn][maxn][2 * maxn];
int main()
{
scanf("%d%d%d", &N, &L, &K);
for (int i = 0; i < N; ++i)
scanf("%lf", P + i), P[i] /= 100;
for (int i = 0; i < N; ++i)
scanf("%d", A + i);
dp[0][0][N + K] = 1;
for (int i = 0; i < N; ++i)
for (int j = 0; j <= i; ++j)
for (int k = N - j; k <= 2 * N; ++k)
{
dp[i + 1][j + 1][min(k + A[i], 2 * N)] += dp[i][j][k] * P[i];
dp[i + 1][j][k] += dp[i][j][k] * (1 - P[i]);
}
double res = 0;
for (int j = L; j <= N; ++j)
for (int k = N; k <= 2 * N; ++k)
res += dp[N][j][k];
printf("%.6f\n", res);
return 0;
}