HDU_完全背包系列

HDU_1114 Piggy-Bank

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 20378    Accepted Submission(s): 10361


Problem Description
Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid. 

But there is a big problem with piggy-banks. It is not possible to determine how much money is inside. So we might break the pig into pieces only to find out that there is not enough money. Clearly, we want to avoid this unpleasant situation. The only possibility is to weigh the piggy-bank and try to guess how many coins are inside. Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency. Then there is some minimum amount of money in the piggy-bank that we can guarantee. Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank. We need your help. No more prematurely broken pigs! 
 

Input
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers E and F. They indicate the weight of an empty pig and of the pig filled with coins. Both weights are given in grams. No pig will weigh more than 10 kg, that means 1 <= E <= F <= 10000. On the second line of each test case, there is an integer number N (1 <= N <= 500) that gives the number of various coins used in the given currency. Following this are exactly N lines, each specifying one coin type. These lines contain two integers each, Pand W (1 <= P <= 50000, 1 <= W <=10000). P is the value of the coin in monetary units, W is it's weight in grams. 
 

Output
Print exactly one line of output for each test case. The line must contain the sentence "The minimum amount of money in the piggy-bank is X." where X is the minimum amount of money that can be achieved using coins with the given total weight. If the weight cannot be reached exactly, print a line "This is impossible.". 
 

Sample Input
  
  
3 10 110 2 1 1 30 50 10 110 2 1 1 50 30 1 6 2 10 3 20 4
 

Sample Output
  
  
The minimum amount of money in the piggy-bank is 60. The minimum amount of money in the piggy-bank is 100. This is impossible.
 
题意:给出猪猪存钱罐的净重E以及存了钱后的重量F,用给出的N种硬币(重量W,价值P)凑成所存钱的最小价值。
分析:完全背包。
代码清单:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 500 + 5;
const int maxw = 10000 + 5;
const int maxa = 1e9 + 5;

int T;
int E, F;
int N;
int P[maxn];
int W[maxn];
int dp[maxw];

void input() {
	
	cin >> E >> F;
	cin >> N;
	for(int i = 0; i < N; ++i) {
		cin >> P[i] >> W[i];
	}
}

void solve() {

	int V = F - E;
	
	if(V == 0) {
		cout << "The minimum amount of money in the piggy-bank is 0." << endl;
		return ;
	}

	dp[0] = 0;
	for(int i = 1; i <= V; ++i) {
		dp[i] = maxa;
	}

	for(int i = 0; i < N; ++i) {
		for(int j = W[i]; j <= V; ++j) {
			dp[j] = min(dp[j - W[i]] + P[i], dp[j]);
		}
	}

	if(dp[V] == maxa) {
		cout << "This is impossible." << endl;
	}
	else {
		cout << "The minimum amount of money in the piggy-bank is ";
		cout << dp[V] << "." << endl;
	}
}

int main() {
	
	cin >> T;
	for(int t = 0; t < T; ++t) {
		input();
		solve();
	}
	return 0;
}


HDU_1248 寒冰王座

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 14859    Accepted Submission(s): 7632


Problem Description
不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前.

死亡骑士:"我要买道具!"

地精商人:"我们这里有三种道具,血瓶150块一个,魔法药200块一个,无敌药水350块一个."

死亡骑士:"好的,给我一个血瓶."

说完他掏出那张N元的大钞递给地精商人.

地精商人:"我忘了提醒你了,我们这里没有找客人钱的习惯的,多的钱我们都当小费收了的,嘿嘿."

死亡骑士:"......"

死亡骑士想,与其把钱当小费送个他还不如自己多买一点道具,反正以后都要买的,早点买了放在家里也好,但是要尽量少让他赚小费.

现在死亡骑士希望你能帮他计算一下,最少他要给地精商人多少小费.
 

Input
输入数据的第一行是一个整数T(1<=T<=100),代表测试数据的数量.然后是T行测试数据,每个测试数据只包含一个正整数N(1<=N<=10000),N代表死亡骑士手中钞票的面值.

注意:地精商店只有题中描述的三种道具.
 

Output
对于每组测试数据,请你输出死亡骑士最少要浪费多少钱给地精商人作为小费.
 

Sample Input
   
   
2 900 250
 

Sample Output
   
   
0 50
 

FATE

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


Problem Description
最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务。久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级。现在的问题是,xhd升掉最后一级还需n的经验值,xhd还留有m的忍耐度,每杀一个怪xhd会得到相应的经验,并减掉相应的忍耐度。当忍耐度降到0或者0以下时,xhd就不会玩这游戏。xhd还说了他最多只杀s只怪。请问他能升掉这最后一级吗?
 

Input
输入数据有多组,对于每组数据第一行输入n,m,k,s(0 < n,m,k,s < 100)四个正整数。分别表示还需的经验值,保留的忍耐度,怪的种数和最多的杀怪数。接下来输入k行数据。每行数据输入两个正整数a,b(0 < a,b < 20);分别表示杀掉一只这种怪xhd会得到的经验值和会减掉的忍耐度。(每种怪都有无数个)
 

Output
输出升完这级还能保留的最大忍耐度,如果无法升完这级输出-1。
 

Sample Input
   
   
10 10 1 10 1 1 10 10 1 9 1 1 9 10 2 10 1 1 2 2
 

Sample Output
   
   
0 -1 1
 
分析:二维完全背包。dp[i][j]表示忍耐度为i、最多杀怪数为j的最大经验值。
代码清单:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 100 + 5;

int n, m, k, s;
int a[maxn], b[maxn];
int dp[maxn][maxn];


void input() {
	
	for(int i = 0; i < k; ++i) {
		scanf("%d%d", &a[i], &b[i]);
	}
}

void solve() {
	
	memset(dp, 0, sizeof(dp));
	
	int usedm = 0;
	
	for(int i = 1; i <= m; ++i) {
		for(int ki = 0; ki < k; ++ki) {
			if(i < b[ki]) continue;
			for(int j = 1; j <= s; ++j) {
				for(int jj = 1; jj <= j && jj * b[ki] <= i; ++jj) {
					dp[i][j] = max(dp[i - jj * b[ki]][j - jj] + jj * a[ki], dp[i][j]);
				}
			}
		}
		if(dp[i][s] >= n) { usedm = i; break; }
	}

	if(usedm == 0) printf("-1\n");
	else printf("%d\n", m - usedm);
}

int main() {
	
	while(scanf("%d%d%d%d", &n, &m, &k, &s) != EOF) {
		input();
		solve();
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值