您的位置:首页 > 其它

poj 1014 Dividing(多重背包)

2014-04-26 17:10 302 查看
题目大意:

有价值分别为1到6的6种大理石,两个小伙伴在分财产,想要尽可能的公平的划分,问你能不能分出来。

Sample Input

6个数字,分别表示六块大理石的数量。

全部为0时输入结束

多种物品分别有不同的价值跟重量,典型的多组背包。

把背包的容量设为总价值的一半,看能不能装满。

注意dp数组的大小。。。RE了我好几次。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int N =60010;

bool dp
;

int V;

void ZeroOnePack(int cost)/*01背包*/
{
for(int i = V ; i >= cost ; i--)
{
dp[i] |= dp[i-cost];
}
}

void CompletePack(int cost)/*完全背包*/
{
for(int i = cost ; i <= V ; i++)
{
dp[i] |= dp[i - cost];
}
}

void MultiplePack(int cost , int amount)
{
if(cost * amount >= V)
{
CompletePack(cost);
}
else/*二进制优化01背包*/
{
int k = 1;
while(k < amount)
{
ZeroOnePack(cost*k);
amount -= k;
k <<= 1;
}
ZeroOnePack(cost*amount);
}
}

int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int a[10];
int cnt = 1;
while(1)
{
bool flag = false;
int sum = 0;
memset(dp,false,sizeof(dp));
dp[0] = true;
for(int i = 1 ; i <= 6 ; i++)
{
scanf("%d",&a[i]);
if(a[i] != 0)
{
flag = true;
sum += a[i]*i;
}
}
if(!flag)
{
break;
}
if(sum%2)
{
printf("Collection #%d:\nCan't be divided.\n\n",cnt++);
}
else
{
V = sum >> 1;
for(int i = 1 ; i <= 6 ; i++)
{

MultiplePack(i,a[i]);
}
if(dp[V])
{
printf("Collection #%d:\nCan be divided.\n\n",cnt++);
}
else
{
printf("Collection #%d:\nCan't be divided.\n\n",cnt++);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: