Topic links
Test instructions
Rob Bank (this background favorite), there are n banks, each bank robbery is caught the probability is p[i], you think when the probability of being caught below P is safe.
Ask, how much money can you rob at most.
Ideas:
Abstract into knapsack problems, each bank has only two options, either to rob or not to rob.
The probability of being caught is a bit hard to find, because it has to be considered before being caught. This is replaced by a mutex event: the probability of not being caught.
Probabilities are weights, money is weight, state transfer equation:
Dp[i] = max (Dp[i], Dp[i-money[j]] * (1-p[j]))
Finally, in Dp[money_count] find a satisfying probability greater than p maximum subscript can be.
Code:
1#include <cmath>2#include <cstdio>3#include <cstring>4#include <cstdlib>5#include <ctime>6#include <Set>7#include <map>8#include <list>9#include <queue>Ten#include <string> One#include <vector> A#include <fstream> -#include <iterator> -#include <iostream> the#include <algorithm> - using namespacestd; - #defineLL Long Long - #defineINF 0x3f3f3f3f + #defineMAXN 10010 - #defineMOD 1000000007 + #defineEPS 1e-6 A DoubleDP[MAXN]; at intW[MAXN]; - DoubleV[MAXN]; - intN; - Doublep; - voidShowintV) - { in for(inti =0; I <= V; i + +) -printf (dp[i] = = INF?"INF,":"%.3LF,", Dp[i]); toprintf"\ n"); + } - voidZeroonepack (intVintN) the { *Fill (DP, DP + V +1,0); $ Panax Notoginsengdp[0] =1.0; - for(inti =0; I < n; i + +) the for(intj = V; J >= W[i]; J--) +DP[J] = max (Dp[j], Dp[j-w[i]] * (1-v[i])); A } the + intMain () - { $ intT; $ intKcase =0; -scanf"%d", &T); - while(T--) the { - intV =0;Wuyiscanf"%lf%d", &p, &n); the for(inti =0; I < n; i + +) - { Wuscanf"%d%lf", &w[i], &v[i]); -V + =W[i]; About } $ Zeroonepack (V, n); - intAns =0; - for(inti =0; I <= V; i + +) - if(Dp[i] > (1-p)) AAns =Max (ans, i); +printf"Case %d:%d\n", ++kcase, ans); the } - return 0; $}View Code
lightoj_1079 Just Another robbery