您的位置:首页 > 其它

hdu 1171 dp(多重背包)

2012-04-15 15:14 260 查看
View Code

//hdu 1171 dp(多重背包)

//题意:把所有物品的价值尽量分为相等的两份,不能等分的话
//后面那份可以稍小于前面的
//求出价值总和后,令价值的一半为背包容量,让背包尽可能的装满

#include <stdio.h>
#include <string.h>

//最多50种,每种最多100个,每个价值最大50
//所以所有物品总价值为250000,我们只要dp一半就可以了
#define N 130000
#define M 55

int tot_n;
int val[M], num[M];
bool dp
;

int main()
{
while(scanf("%d", &tot_n), tot_n >= 0)
{
int sum_v = 0;
memset(dp, false, sizeof(dp));
for(int i = 0; i < tot_n; ++i)
{
scanf("%d%d", &val[i], &num[i]);
sum_v += val[i] * num[i];
}
int half = sum_v / 2;
dp[0] = true;
for(int i = 0; i < tot_n; ++i)
{   //j 要从后往前,若从0开始,i=0 时(即第i中物品时),在s循环中,
//val[i]*s = 10, j = 0的话,val[10] 就会为true,当j 等于10时 又把i种物品放一次
//但 dp[10] 本应该是 false 的
//若j 从大到小,比如 j = 10时 dp为true,然后放入 val[i]=10 的物品,则标记val[10+10]=true
//意思是 容纳的质量为 10 时放入 质量为 10 的物品,则容纳的质量可达到20,则标记为true
//标记的是 j 的后面,而j 时递减的,所以不会影响到 dp[j] == true这个判断

if(half - val[i] >= 0)  //没有这个判断就会超时,也不知道为什么
{                       //for 的判断应该就会判断了,但他就是超时了,无语
for(int j = half - val[i]; j >= 0; --j)  //表示背包已经装有 j 的容量
{
if(dp[j] == true)
{   //s记录i中器材的数量
for(int s = 1; s <= num[i] && val[i]*s + j <= half; s++)
dp[ val[i]*s + j ] = true;
}
}
}
}
int i;
for(i = half; i >= 0; --i)  //找背包尽可能装满的大小
if(dp[i] == true)
break;
printf("%d %d\n", sum_v - i, i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: