HDU - 2955 Robberies(01背包)

来源:互联网 发布:淘宝开企业店铺的条件 编辑:程序博客网 时间:2024/04/29 20:31

题目大意:给出N个银行里存放的钱和抢劫了该银行被捕的概率
要求你找出能抢劫的最多的钱,且被捕概率要小于等于Q

解题思路:01背包问题
用dp[i]表示抢劫了i的钱,没有被捕的最大概率
则转移方程为
dp[i] = max(dp[i], dp[i - val] * (1 - cost))
其中的1-cost表示的是不被捕捉到的概率

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int N = 10010;int n, Sum;double p;int val[N];double c[N], dp[N];void init() {    scanf("%lf%d", &p, &n);    Sum = 0;    for (int i = 0; i < n; i++) {        scanf("%d%lf", &val[i], &c[i]);        Sum += val[i];    }}void solve() {    memset(dp, 0, sizeof(dp));    dp[0] = 1;    for (int i = 0; i < n; i++)        for (int j = Sum; j >= val[i]; j--)            dp[j] = max(dp[j], dp[j - val[i]] * (1 - c[i]));    for (int i = Sum; i >= 0; i--) {        if (dp[i] > 1 - p) {            printf("%d\n", i);            return ;        }    }}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();        solve();    }    return 0;}
0 0