codeforces 167B
题意:
给 定 一 个 初 始 容 量 为 k 的 背 包 , 你 背 上 它 去 打 n 场 比 赛 , 第 i 场 比 赛 获 胜 的 概 率 为 p i , 奖 励 为 a i 。 给定一个初始容量为k的背包,你背上它去打n场比赛,第i场比赛获胜的概率为p_i,奖励为a_i。 给定一个初始容量为k的背包,你背上它去打n场比赛,第i场比赛获胜的概率为pi,奖励为ai。
- 若 a i = − 1 , 你 可 以 获 得 体 积 为 1 的 奖 品 若a_i=-1,你可以获得体积为1的奖品 若ai=−1,你可以获得体积为1的奖品
- 若 a i ≠ − 1 , 你 可 以 将 背 包 容 量 扩 充 a i 若 a_i≠-1,你可以将背包容量扩充a_i 若ai̸=−1,你可以将背包容量扩充ai
问 至 少 获 胜 l 场 比 赛 并 且 将 所 有 已 得 奖 品 带 走 的 概 率 。 问至少获胜l场比赛并且将所有已得奖品带走的概率。 问至少获胜l场比赛并且将所有已得奖品带走的概率。
题解:
d
p
[
i
]
[
j
]
[
k
]
表
示
前
i
场
比
赛
获
胜
j
场
,
剩
余
背
包
容
量
为
k
的
概
率
。
dp[i][j][k]表示前i场比赛获胜j场,剩余背包容量为k的概率。
dp[i][j][k]表示前i场比赛获胜j场,剩余背包容量为k的概率。
为
避
免
状
态
转
移
时
背
包
容
量
出
现
负
值
的
情
况
,
以
200
+
k
代
替
k
。
为避免状态转移时背包容量出现负值的情况,以200+k代替k。
为避免状态转移时背包容量出现负值的情况,以200+k代替k。
- 第 i 场 比 赛 输 , d p [ i ] [ j − 1 ] [ k ] = d p [ i − 1 ] [ j − 1 ] [ k ] ∗ ( 1 − p [ i ] ) 第i场比赛输,dp[i][j-1][k]=dp[i-1][j-1][k]*(1-p[i]) 第i场比赛输,dp[i][j−1][k]=dp[i−1][j−1][k]∗(1−p[i])
- 第 i 场 比 赛 赢 且 k + a [ i ] ≥ 0 时 , d p [ i ] [ j ] [ k + a [ i ] ] = d p [ i − 1 ] [ j − 1 ] [ k ] ∗ p [ i ] 第i场比赛赢且k+a[i]≥0时,dp[i][j][k+a[i]]=dp[i-1][j-1][k]*p[i] 第i场比赛赢且k+a[i]≥0时,dp[i][j][k+a[i]]=dp[i−1][j−1][k]∗p[i]
#include <bits\stdc++.h>
using namespace std;
const int N = 201;
int a[N];
double p[N];
double dp[N][N][N*2];
int main() {
int n, l, k;
cin >> n >> l >> k;
for(int i = 1 ; i <= n ; i++){
cin >> p[i];
p[i] /= 100;
}
for(int i = 1 ; i <= n ; i++){
cin >> a[i];
}
dp[0][0][200+k] = 1;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= i ; j++){
for(int k = 0 ; k <= 400 ; k++){
dp[i][j-1][k] += dp[i-1][j-1][k]*(1-p[i]);
int r = min(400, k+a[i]);
if(r >= 0){
dp[i][j][r] += dp[i-1][j-1][k]*p[i];
}
}
}
}
double ans = 0;
for(int j = l ; j <= n ; j++){
for(int k = 200 ; k <= 400 ; k++){
ans += dp[n][j][k];
}
}
cout << setiosflags(ios::fixed) << setprecision(12) << ans << endl;
return 0;
}