ZOJ1149 POJ1014 HDU1059 Dividing,多重背包问题

本文通过一个具体的编程实例,深入解析了多重背包问题的解决方法。文章详细介绍了如何将多重背包问题转换为0/1背包问题,并给出了完整的C++实现代码。通过对物品数量进行二进制拆分,有效地减少了状态数,提高了算法效率。

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

很经典的多重背包问题,大家可以看看《背包九讲》里面的第三讲。



/*******************************************************************************
 # Author : Neo Fung
 # Email : neosfung@gmail.com
 # Last modified: 2011-10-02 20:46
 # Filename: ZOJ1149 POJ1014 HDU1059 Dividing.cpp
 # Description : 
 ******************************************************************************/
// #include "stdafx.h"
// #define DEBUG

#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <memory.h>

using namespace std;
int dp[450000],value[200000];

int main(void)
{
#ifdef DEBUG  
	freopen("data.txt","r",stdin);  
#endif  
	int ind=1;
	int num[7];
	while(scanf("%d %d %d %d %d %d",&num[1],&num[2],&num[3],&num[4],&num[5],&num[6])!=EOF)
	{
		int total=0;
		for(int i=1;i<=6;++i)
			total+=i*num[i];
		if(total==0) break;
		printf("Collection #%d:\n",ind++);
		if(total%2)
		{
			printf("Can't be divided.\n\n");
			continue;
		}
		int half=total/2;
		int ncount=0;
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=6;++i)	//二进制拆分
		{
			int temp=num[i];
			if(temp==0) continue;
			int pow2=1;
			while(temp>pow2)
			{
				value[ncount++]=pow2*i;
				temp-=pow2;
				pow2*=2;
			}
			if(temp) value[ncount++]=temp*i;
		}
		for(int i=0;i<ncount;++i)	//转变为0/1背包问题
			for(int j=half;j>=value[i];--j)
				dp[j]=max(dp[j],dp[j-value[i]]+value[i]);
		if(dp[half]==half)
			printf("Can be divided.\n\n");
		else
			printf("Can't be divided.\n\n");
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值