POJ 1014 Dividing 多重背包

http://poj.org/problem?id=1014

下午A完那题并查集后,滚去睡觉,睡得跟猪一样,半小时后闹钟响了,睁眼一看天是黑的!然后我就抱怨道舍友的疯了呀,闹钟那么早,呃不对怎么这么像我的闹钟?我一看手表,卧槽,5点多,我就很郁闷什么时候脑残把早上的闹钟定到五点多了? 突然想到这是晚上。。。。。。。。哭瞎了 T T

还有呀最近LOL好火的样子,晚上在学校举办LOL决赛- -|||

当然我是不会玩这种游戏滴~

----------------------------------------------------------邪恶的分割线----------------------------------------------------------

题目大意:

给定6种价值分别为1~6的物品,输入6个数代表他们的数量,问一下能不能把他们的价值等分。

思路:

多种背包问题:有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值
是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

很显然这题的模型就是多重背包。。只不过费用和价值一样,直接套背包九讲的模版。。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=20000*6+10;
int n[7];
int N=6;
int dp[MAXN];
int volume;
void CompletePack(int cost,int weight) 
{
		for(int v=cost;v<=volume;v++)
		{
			 dp[v]=max(dp[v],dp[v-cost]+weight);  
		}
}

void ZeroOnePack(int cost,int weight) 
{
		for(int v=volume;v>=cost;v--)
		{
			 dp[v]=max(dp[v],dp[v-cost]+weight);  
		}
}

void MultiplePack(int cost,int weight,int amount)
{
	if(cost * amount >= volume)
	{
			CompletePack(cost,weight);
			return;
	}
	int k=1;

	while(k<amount)
	{
		ZeroOnePack(k*cost,k*weight);
		amount-=k;
		k<<=1;
	}
	ZeroOnePack(amount *cost  , amount *weight);
}

int main()
{
	int kase=1;
	while(1) 
	{
		volume=0;
		for(int i=1;i<=N;i++)
		{
				scanf("%d",&n[i]);
				volume+=n[i]*i;
		}

		if(!volume)
			break;
		
		printf("Collection #%d:\n",kase++);
		if(volume % 2 !=0)
		{
				printf("Can't be divided.\n\n");
				continue;
		}

		volume>>=1;
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=6;i++)
		{
			MultiplePack( i , i , n[i] );
		}
		
		bool ok=false;
		for(int i=0;i<MAXN;i++)
		{
				if(dp[i]==volume)
				{
					ok=true;
				}
		}

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


你可能感兴趣的:(POJ 1014 Dividing 多重背包)