Just another Robbery(概率&01背包)
Posted Are~you~ready
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Just another Robbery(概率&01背包)相关的知识,希望对你有一定的参考价值。
题目:https://vjudge.z180.cn/problem/LightOJ-1079
题意:首先给你一个最大被抓的概率p和n家银行,每一家银行有一个金钱wi和被抓概率pi,问在不超过p的前提下,最多能够获得多少金钱。
题解:01背包,把金钱当背包容量,1-pi当价值,然后求价值最大就好,再从大到小扫一遍背包,找到第一个大于1-p的那个背包容量,就是答案,,,pi是被抓概率,转化为1-pi就是不被抓概率,那么求在当前背包容量下不被抓概率的最大值。
#include <algorithm> #include <bitset> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <deque> #include <functional> #include <iostream> #include <map> #include <queue> #include <set> #include <stack> #include <string> #include <vector> //#include <unordered_map> //#include <unordered_set> //#include <bits/stdc++.h> //#define int long long #define pb push_back #define PII pair<int, int> #define mpr make_pair #define ms(a, b) memset((a), (b), sizeof(a)) #define x first #define y second typedef long long ll; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3f; const int N = 1e7 + 7; using namespace std; double f[N], v[N]; int w[N]; // signed main(){ int main(int argc, char const *argv[]) { int T; // printf("%.10lf\\n",-1e8+(-0.02)); int Case = 0; scanf("%d", &T); while (T--) { int n; double p; for (int i = 1; i <= 10000; i++) f[i] = 0; //总的金钱和不超过10000 scanf("%lf%d", &p, &n); p = 1 - p; //求不被抓的概率 for (int i = 1; i <= n; i++) { int val; double pi; scanf("%d%lf", &val, &pi); w[i] = val, v[i] = 1 - pi; //存不被抓的概率,用w[i]当体积 } f[0] = 1; // dp入口 for (int i = 1; i <= n; i++) { for (int j = 10000; j >= w[i]; j--) { //找那个小容量的不被抓的概率,再乘以我这个不被抓的概率 //就是到这一步不被抓的概率 f[j] = max(f[j], (f[j - w[i]]) * v[i]); } } int pos = 0; for ( int i = 10000; i >= 1; i--) { //从最大开始找一个不被抓的概率大于我的p(这里的p已经处理为不被抓的概率) if ((f[i]) >= p) { pos = i; //记录位置输出 break; } } printf("Case %d: ", ++Case); printf("%d\\n", pos); } return 0; }
以上是关于Just another Robbery(概率&01背包)的主要内容,如果未能解决你的问题,请参考以下文章
LightOJ 1079 Just another Robbery (01背包)
[LightOJ 1079] Just another Robbery
HDU 2955 Robberies && LightOJ 1079 Just another Robbery