poj 1014 Dividing 多重背包问题

问是否平分N的物品的价值

先求出N个物品的价值总和

如何是奇数,则一定不能平分

如果是偶数,则half = total/2


既题目转化为给定多重背包的N个物品,为是否能装满half的背包,如果可以,则可以平分。


#include <iostream>
#include <stdio.h>


#include <cstring>
using namespace std;


#define MAX_V (6+1)
#define MAX_F (1000000+1)  
//#define printf //

int Amount[MAX_V];
bool F[MAX_F];  
int n=6,m;
void ZeroOnePack(int value)
{
	//printf("zero one pack value:%d\n",value);
	for(int v=m;v>=value;--v)
	{
		F[v] |= F[v-value];
	//	printf("F[%d] = %d\n",v,F[v]);
	}
}
void CompletePack(int value)
{
	for(int v=value;v<=m;v++)
		F[v] |= F[v-value];
}
void MultiPack(int value,int amount)
{

	if(value * amount >= m)
	{

		CompletePack(value);
		return;
	}
	int k=1;
	while(k<amount)
	{
		ZeroOnePack(value * k);
		amount -= k;
		k <<= 1;
	}
	if(amount)
		ZeroOnePack(value*amount);
}
int main()
{
	int k=1;
	while(true)
	{
		bool iFound = false;
		int total = 0,half;
		int ret = 0;
		memset(F,0,sizeof(F));
		F[0]=true;
		for(int i=1;i<MAX_V;i++)
		{
			cin >> Amount[i];
			//printf("i=%d Amount[%d]=%d\n",i,i,Amount[i]);
			if(Amount[i] != 0)
				iFound = true;

			total += i * Amount[i];
		}
		if(!iFound)
			break;

		if(total % 2 != 0)
			ret = 0;	
		else
		{
			half = total/2;
			m = half;

			for(int i=1;i<MAX_V;i++)
				if(Amount[i])
					MultiPack(i,Amount[i]);

			if(F[m])
				ret = 1;
		}
		

		printf("Collection #%d:\n",k++);

		if(ret)
			printf("Can be divided.\n");
		else
			printf("Can't be divided.\n");
		printf("\n");
	
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值