HDU1171 Big Event in HDU

本文详细介绍了杭电计算机学院在2002年分拆为计算机学院和软件学院时遇到的设备分配问题。该问题被转化为一个多重背包问题,要求设备价值尽可能平均分配。通过动态规划的思路,实现了一维数组优化的解决方案,以找到最优设备分配策略,确保两个学院设备总价值的平衡。同时,文章中提到了一些细节处理和代码实现,对于理解多重背包问题及其优化方法具有指导意义。

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

题目链接
题目描述:

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).

题目翻译:

如今,我们都知道计算机学院是杭电最大的系。但是,你或许不知道计算机学院在2002年被划分为计算机学院和软件学院,这在杭电绝对称得上是一件大事,同时也是一件麻烦的事。所有的设备要尽可能平均地分到两个学院(指两个学院得到的设备的价值尽可能平均)。首先所有的设备都经过评估,如果两个设备的价值相同,这两个设备则被认为是相同的。这里假设有N种设备(不同的价值),每种设备的价值为V,数量为M。输出AB,分别代表两个学院最后分到的设备的总价值,其中A不小于B。

解题思路:

可以发现,这是一道多重背包问题
题目要求所有的设备尽可能平均地分到两个学院,那么可以知道其中一个学院B分到的设备的价值要尽可能接近总价值的一半,另一个学院A得到的价值就是总价值-B得到的价值
如此一来,我们可以用数组f[i][j] 表示前 i 个物品,价值为 j(相当于背包的容量)时能得到的最大价值。最后学院B得到的价值就是f[n][sum/2],其中sum表示总价值,学院A得到的价值就是sum-f[n][sum/2]
代码部分就和其他多重背包问题大同小异了,如果看不懂,可以参考我之前写得博客
多重背包问题(暴力、二进制优化、单调队列优化)
并且这里需要把二维数组f优化成一维的,不然会超内存,可以参考这篇博客
01背包问题的“优化空间复杂度:O(N*V)->O(V)”部分

代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
const int N = 251000;
int f[N],v[60],m[60];
int main() {
//	freopen("1.txt","r",stdin);
	int n,sum=0;
	while(cin>>n&&n>0) {
		memset(f,0,sizeof f);
		f[0]=0;
		sum=0;
		for(int i=1;i<=n;i++){
			cin>>v[i]>>m[i];
			sum+=v[i]*m[i];
		}
		for(int i=1; i<=n; i++) {
			for(int j=sum; j>=1; j--) {
				for(int k=1; k<=m[i]; k++) {
					if(j>=v[i]*k) {
						f[j]=max(f[j],f[j-v[i]*k]+v[i]*k);
					}
				}
			}
		}
		int a,b;
		a=f[sum/2],b=sum-a;
		cout<<max(a,b)<<" "<<min(a,b)<<endl;
	}
	return 0;
}
总结:

题目是不难写了,就是有些细节需要注意,因为细节WA了好几次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值