hdu 2955 Robberies(0/1背包)

题意:给出背包容量P,物品数量N,然后分别给出每一个物品的价值与体积,求该背包能装下最大的价值是多少?(根据原文改编)

思路:把最小概率改成最大概率,把价值做下标,数组值存概率。

因为背包是有序的,从后往前找,找到第一个满足条件的概率就是最大的价值。

注意:

1)题目是求小于给定的P的情况下,求出最大的价值;

2)动态转移方程的下标是价值,那么数组大小就要开sum大小,定义时最好开的足够大。


java代码:


import java.util.Scanner;

public class Main {
	/*
	 * dp-下标表示价值,dp[i]表示概率
	 */
	static int t, m, sum, a;
	static double p, b;
	static Bank[] banks = new Bank[105];
	static double[] dp = new double[50000];

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		t = sc.nextInt();
		while (t-- > 0) {
			p = 1 - sc.nextDouble();// 不被抓的最小概率
			m = sc.nextInt();
			sum = 0;
			for (int i = 0; i < m; i++) {
				a = sc.nextInt();
				b = 1 - sc.nextDouble();// 不被抓的概率
				banks[i] = new Bank(a, b);
				sum += a;
			}
			for (int i = 1; i <= sum; i++) {
				dp[i] = 0;
			}
			dp[0] = 1.0;
			for (int i = 0; i < m; i++) {
				for (int j = sum; j - banks[i].money >= 0; j--) {
					dp[j] = max(dp[j], dp[j - banks[i].money] * banks[i].jail);
				}
			}
			/*
			 * 找到第一个不被抓的概率大于P,
			 * 那么这个概率就是能够获得最大的钱数。
			 */
			for (int i = sum; i >= 0; i--) {
				if (dp[i] > p) {
					System.out.println(i);
					break;
				}
			}
		}
	}

	private static double max(double a, double b) {
		return a > b ? a : b;
	}

}

/*
 * Bank-银行
 */
class Bank {
	/*
	 * money-美元
	 * jail-监狱
	 */
	int money;
	double jail;

	public Bank(int money, double jail) {
		this.money = money;
		this.jail = jail;
	}
}






Robberies

抢劫
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16386    Accepted Submission(s): 6014


Problem Description
The aspiring Roy the Robber has seen a lot of American movies, 
强盗Roy是一个有抱负的人,当他看了大量的美国电影后,
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. 
几个月了,Roy已经评估了几个银行的安全性与银行的现金。
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. 
他的妈妈Ola,不管他的死活。
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. 
输入的第一行包含一个整数T,表示测试事件的个数。
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. 
对于每一个方案的第一行包含一个浮点数P,和整数N,P表示他会执行计划的概率,N表示他计划抢劫的银行数目。
Then follow N lines, where line j gives an integer Mj and a floating point number Pj . 
接下来有N行,在第j行给一个整数Mj和浮点数Pj。
Bank j contains Mj millions, and the probability of getting caught from robbing it is Pj .
 第j个银行有10Mj亿美元,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
  
  
3 0.04 3 1 0.02 2 0.03 3 0.05 0.06 3 2 0.03 2 0.03 3 0.05 0.10 3 1 0.03 2 0.02 3 0.05
 

Sample Output
  
  
2 4 6
 

Source

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值