(hdu step 3.3.1)Big Event in HDU(01背包:N件物品放在容量为V的背包中,第i件物品的费用是c[i],价值是w[i]。问所能获取的最大价值)

本文深入探讨了01背包问题的概念及其解决方法,通过实例解析如何使用动态规划来求解问题,并提供了完整的代码实现。对于计算机科学领域的学习者而言,了解此问题有助于加深对算法的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Big Event in HDU

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 854 Accepted Submission(s): 345

Problem Description
Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).
 

Input
Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.
 

Output
For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.
 

Sample Input
2
10 1
20 1
3
10 1 
20 2
30 1
-1
 

Sample Output
20 10
40 40
 

Author
lcy


题目分析

                         这是属于背包九讲中的《01 背包》。所谓的01背包,也就是说每种物品只有两种状态,放或者不放。这道题中,只要求出了software college所能获取的最大价值,那么computer college所能获取的最大价值也就知道了。所以将software college所能获取的最大价值sum/2设为背包的最大容量V。在这道题中,每件物品的价值w[i]同样作为了费用c[i]。。。。只要明白以上的思路,想必编码也就不困难了。。。



代码如下:

/*
 * a.cpp
 *
 *  Created on: 2015年2月12日
 *      Author: Administrator
 */

#include <iostream>
#include <cstdio>

using namespace std;

const int maxn = 5005;
const int maxm = 250005;
int w[maxn];//用于记录每种物品的价值
int f[maxm];//用于记录容量为v时所能获取的最大价值

int main() {
	int n;
	while (scanf("%d", &n) != EOF, n > 0 ) {//对于n为-1时结束的处理为n>0

		memset(w,0,sizeof(w));//重置费用/价值为0。其实在这里重不重置都没有影响
		memset(f,0,sizeof(f));//重置充值或能获取的最大价值为0。这个数组一定要重置,否则可能影响状态转移方程f[v] = max(f[v],f[v - c[i]] + w[i]);


		int v, m;
		int sum = 0;//所有商品的总价值
		int i;
		int j;
		int cnt = 0;
		for (i = 0; i < n; ++i) {//遍历每种物品
			scanf("%d%d", &v, &m);

			sum += v*m;//将每种物品的总价值加到所有商品的总价值中

			for (j = 0; j < m; ++j) {
				w[cnt++] = v;//记录每一种物品的价值
			}
		}

		cnt -= 1;

		for (i = 0; i < cnt; ++i) {
			for (j = sum / 2; j >= w[i]; --j) {
				/**
				 * 将其展开为f[i][j] = max(f[i-1][j],f[i-1][j-w[i]]+w[i])来理解
				 * 即:前i件物品放在容量为j的背包时所能获取的最大价值是
				 * 第i-1件物品放在容量j的背包中所能获得最大值(不放第i件物品在背包中)与
				 * 第i-1件物品放在容量为j-w[i]的背包中所能达到的最大值(这是腾出地方放第i件物品)
				 * 中的最大值
				 */
				f[j] = max(f[j], f[j - w[i]] + w[i]);
			}
		}

		//一个学院能获取的价值是f[sum / 2],那么另一个能获取的自然是sum - f[sum / 2]了
		printf("%d %d\n", sum - f[sum / 2], f[sum / 2]);
	}

	return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅气的东哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值