题目链接:点击打开链接
题意:
有个人想偷钱,但是有风险;
求在给定的风险下偷到最多的钱;
理解:
一开始认为是简单的01背包,把概率放大10000倍还是WA。。
然后换思路了,神的理解是;
把风险的另一面拿出来,就是没有风险的一面;
考虑在偷到 x 这么多钱的情况下,最大的没有风险的值位多少;
这样递推式就是:dp[x] = max(dp[x], dp[x - v[i]] * (1 - p[i]));
神的解说说的是这样的:风险概率乘起来不代表风险概率,而不风险的概率乘起来的却是不风险的概率。不懂啊!
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MIN_INF = 1e-7;
const int MAX_INF = (1e9) + 7;
#define X first
#define Y second
int main() {
int t;
cin >> t;
while (t--) {
double P, n;
cin >> P >> n;
vector<int> v(n + 2);
vector<double> p(n + 2);
int sum = 0;
for (int i = 1; i <= n; ++i) {
cin >> v[i] >> p[i];
sum += v[i];
}
vector<double> dp(10111, 0);
dp[0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = sum; j >= 0; --j) {
if (j >= v[i]) {
dp[j] = max(dp[j], dp[j - v[i]] * (1 - p[i]));
}
}
}
for (int i = sum; i >= 0; --i) {
if (dp[i] >= (1 - P)) {
cout << i << endl;
break;
}
}
}
return 0;
}