hdu 2955 Robberies 01背包

来源:互联网 发布:深入理解php原理 编辑:程序博客网 时间:2024/06/05 22:58

Robberies

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 25589    Accepted Submission(s): 9432

Problem Description
The aspiring Roy the Robber has seen a lot of American movies, and knows that the bad guys usually gets caught in the end, often because they become too greedy. He has decided to work in the lucrative business of bank robbery only for a short while, before retiring to a comfortable job at a university.


For a few months now, Roy has been assessing the security of various banks and the amount of cash they hold. He wants to make a calculated risk, and grab as much money as possible.
His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this. 

Input
The first line of input gives T, the number of cases. For each scenario, the first line of input gives a floating point number P, the probability Roy needs to be below, and an integer N, the number of banks he has plans for. Then follow N lines, where line j gives an integer Mj and a floating point number Pj . 
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj . 

Output
For each test case, output a line with the maximum number of millions he can expect to get while the probability of getting caught is less than the limit set.

Notes and Constraints
0 < T <= 100
0.0 <= P <= 1.0
0 < N <= 100
0 < Mj <= 100
0.0 <= Pj <= 1.0
A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.
 
Sample Input
30.04 31 0.022 0.033 0.050.06 32 0.032 0.033 0.050.10 31 0.032 0.023 0.05
 
Sample Output
246
 
Source
IDI Open 2009

哇这个01背包真的是,以后好好学英语嗯微笑
已经从网上看了无数个版的题解,终于。
嗯路还长慢慢走。

题意:想抢银行,但是有风险。
第一行是测试组数t,
第二行是抢银行需要低于的概率(浮点型)p和计划抢的银行数n,
接下来n行,第一个数是银行钱数,第二个是被抢概率(浮点型)。
 题解:需要转换,把银行钱数j当成背包 价值v,被抓概率p当成重量p,求最大逃跑概率,然后输出最多的钱。
状态转移方程: dp[j] = max(dp[j],dp[j-bag[i].v]*(1-bag[i].p));  (概率是(1-p1)*(1-p2)*(1-p3)...
#include<stdio.h> #include<string.h> #include<algorithm>  using namespace std;  const int maxn = 50005;double dp[maxn]; struct zeroonebag  //定义01背包{      int v;      double p;  }bag[maxn];   int main()  {      int t,n;      double p;      scanf("%d",&t);     while(t--)      {  //需要低于的概率p,n是银行数,         scanf("%lf%d",&p,&n);         int sum = 0;          for(int i=0; i<n; i++)          { //bag[i].v 是银行钱数 bag[i].p 抢劫概率             scanf("%d%lf",&bag[i].v,&bag[i].p);              sum = sum+bag[i].v;          }          memset(dp,0,sizeof(dp));          dp[0] = 1;  //如果不抢就不会被抓  //外层循环是银行数目,内层循环是银行钱数        for(int i=0; i<n; i++)          {              for(int j=sum; j>=bag[i].v; j--)              {                  dp[j] = max(dp[j],dp[j-bag[i].v]*(1-bag[i].p));              }          }          //抢钱的数目和逃跑的概率成反比,抢的越少,越容易跑         for(int i=sum; i>=0; i--)          {              if(dp[i] > 1-p)  //最大的逃跑概率大于被抓概率 ,这样才不会被抓            {                  printf("%d\n",i);                  break;              }          }      }      return 0;  }  

再附上一个把0.1背包拿出来的,enmmm反正也都一样..o(´^`)o

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn = 50005;double dp[maxn];int v[maxn];double w[maxn];int sum,n;void zerobag(int cost,double weight){for(int i=sum; i>=cost; i--)dp[i] = max(dp[i],dp[i-cost]*(1-weight));}int main(){int t;double p;scanf("%d",&t);while(t--){scanf("%lf%d",&p,&n);sum=0;for(int i=0; i<n; i++){scanf("%d%lf",&v[i],&w[i]);sum += v[i];}memset(dp,0,sizeof(dp));dp[0]=1;for(int i=0; i<n; i++)zerobag(v[i],w[i]);for(int i=sum; i>=0; i--)if(dp[i]>=1-p){printf("%d\n",i);break;}}return 0;}

一花一天堂 一草一世界 一树一菩提 一土一如来 一方一净土 一笑一尘缘 一念一清净。

原创粉丝点击