首页 > 代码库 > 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