首页 > 代码库 > HDU-1171-Big Event in HDU

HDU-1171-Big Event in HDU

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1171

题目大意: n种设备,每种设备价值为v 数量为m  希望 以最小的差距分成两堆   第一堆不能比第二堆少,

 

开始看完这题让我想起了小时候与朋友一起去摘野果后分野果,就是我先拿一个,拿最大的,朋友再拿一个,也剩下的拿最大的,以此推,不过这样的话测试数据都过不了,

让我知道以前看是公平的分野果的方法其实并不是最好的方法。

 

这题我用的是多重背包的的思路:多重背包可行性问题么,以价值为费用,以总价值的一半为背包容量。

代码

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;

int dp[125005];

int main(void)
{
int n,i,j,k;
int v[55],m[55];
while(scanf("%d",&n)==1&&n>=0)
{
memset(dp,0,sizeof(dp));
int s=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&v[i],&m[i]);
s=s+v[i]*m[i];
}
int w=s/2;
for(i=0;i<n;i++)
{
for(j=0;j<=w;j++)
{
for(k=0;k<=m[i]&&k*v[i]<=j;k++)
{
dp[j]=max(dp[j],dp[j-k*v[i]]+k*v[i]);
}
}
}
printf("%d %d\n",s-dp[w],dp[w]);
}
return 0;
}

 

参数

1218MS  780K  733 B    

 

这题可以把多重背包改为01背包

 

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

int v[5005];
int dp[125005];

int main(void)
{
int i,j,k,n,s;
int a,b;
while(scanf("%d",&n)==1&&n>=0)
{
k=0; s=0;
memset(dp,0,sizeof(dp));
for(i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
for(j=0;j<b;j++)
{
v[k++]=a;
s=s+a;
}
}
int w=s/2;
for(i=0;i<k;i++)
{
for(j=w;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+v[i]);
}
}
printf("%d %d\n",s-dp[w],dp[w]);
}
return 0;
}

 

 

参数

765MS 796K 709 B

快一些,省时。

 

刚开始接触背包问题  思维有点难以形成,慢慢来。

 

HDU-1171-Big Event in HDU