您的位置:首页 > 其它

HDU 1059 Dividing 多重背包动态规划

2012-09-30 22:35 267 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1059

题意:

  给出价值分别为1-6的东西 , 输入代表价值为1-6的个数 , 现在问你将这些东西完全平分成两份 , 看能不能

刚好平分.

坑爹:

  我一开始是想用多重背包算出 DP[sum] 然后在看下 DP[sum/2] 是不是刚好是sum的一半 , 但这样会超时

解法:

  用多重背包 把背包的 "体积" 定为总价值的一半就是行了 , 不需要算到 "体积" 为sum .

View Code

#include<iostream>
using namespace std;
const int maxn = 120000 + 10;
int DP[maxn];
int sum;

int max(int a,int b)
{
return a > b ? a : b;
}

void ZeroOnePack(int cost,int weight)
{
int j;
for(j=sum/2; j>=cost; j--)
{
DP[j] = max(DP[j] , DP[j-cost]+weight);
}
}

void CompletePack(int cost,int weight)
{
int j;
for(j=cost; j<=sum/2; j++)
{
DP[j] = max(DP[j] , DP[j-cost]+weight);
}
}

void MultiplePack(int cost,int weight,int amount)
{
if(cost * amount >= sum/2)
{
CompletePack(cost,weight);
return ;
}
int k = 1;
while(k<amount)
{
ZeroOnePack(k*cost,k*weight);
amount = amount - k;
k = k * 2;
}
ZeroOnePack(amount*cost,amount*weight);
}

int main()
{
int k=1;
int num[6];
while(cin>>num[0]>>num[1]>>num[2]>>num[3]>>num[4]>>num[5],num[0]+num[1]+num[2]+num[3]+num[4]+num[5])
{
memset(DP,0,sizeof(DP));
printf("Collection #%d:\n",k++);
int i;
sum = 0;
for(i=0; i<6; i++)
{
sum += ( (i + 1) * num[i] );
}
if(sum%2)
{
cout<<"Can't be divided."<<endl<<endl;
continue;
}
for(i=0; i<6; i++)
{
MultiplePack(i+1,i+1,num[i]);
}
if(DP[sum/2] == sum/2)
{
cout<<"Can be divided."<<endl;
}
else
{
cout<<"Can't be divided."<<endl;
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: