Big Event in HDU(01背包)
2016-07-24 00:00
211 查看
/*
题意:
输入一个数n代表有n种物品,
接下来输入物品的价值和物品的个数;
然后将这些物品分成A B 两份,使A B的价值尽可能相等也就是尽量分的公平一些,如果无法使A B相等,那么就使A多一些;
思路:
先计算这些物品的总价值,然后从这些物品中去一些出来,使他们的价值尽可能的接近总价值的一半,
由此可以想到用01背包的思路;
背包容量是总价值的一半,物品体积等于物品的价值;
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int dp[300000];
int value[10000];
int main()
{
int n;
while(scanf("%d",&n)&&n>0)
{
int weight[n+1];
int sum=0,count=0;
int a=0;
memset(dp,0,sizeof(dp));
memset(value,0,sizeof(value));//多组测试数据,记得将值初始化
for(int i=1; i<=n; i++)
{
scanf("%d%d",&a,&weight[i]);//输入物品的价值和物品的个数
sum+=a*weight[i];//计算总价值
while(weight[i]--)
{
count++;
value[count]=a;//将每(个)物品的价值保存起来,而不是只保存每(种)物品的价值
//因为是将总价值平分
}
}
int k=sum/2;//背包容量是总价值的一半,此时会自动向前取整,所以k可能会比一总值的一半少些,
//所以到最后的结果dp[k]是B的值
//cout<<"k="<<k<<endl;
for(int i=1; i<=count ; i++)
for(int j=k; j>=value[i]; j--)
dp[j]=max(dp[j],dp[j-value[i]]+value[i]);//01背包
printf("%d %d\n",sum-dp[k],dp[k]);//输出A B;
}
return 0;
}
/*
2
10 1
20 1
3
10 1
20 2
30 1
*/
题意:
输入一个数n代表有n种物品,
接下来输入物品的价值和物品的个数;
然后将这些物品分成A B 两份,使A B的价值尽可能相等也就是尽量分的公平一些,如果无法使A B相等,那么就使A多一些;
思路:
先计算这些物品的总价值,然后从这些物品中去一些出来,使他们的价值尽可能的接近总价值的一半,
由此可以想到用01背包的思路;
背包容量是总价值的一半,物品体积等于物品的价值;
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int dp[300000];
int value[10000];
int main()
{
int n;
while(scanf("%d",&n)&&n>0)
{
int weight[n+1];
int sum=0,count=0;
int a=0;
memset(dp,0,sizeof(dp));
memset(value,0,sizeof(value));//多组测试数据,记得将值初始化
for(int i=1; i<=n; i++)
{
scanf("%d%d",&a,&weight[i]);//输入物品的价值和物品的个数
sum+=a*weight[i];//计算总价值
while(weight[i]--)
{
count++;
value[count]=a;//将每(个)物品的价值保存起来,而不是只保存每(种)物品的价值
//因为是将总价值平分
}
}
int k=sum/2;//背包容量是总价值的一半,此时会自动向前取整,所以k可能会比一总值的一半少些,
//所以到最后的结果dp[k]是B的值
//cout<<"k="<<k<<endl;
for(int i=1; i<=count ; i++)
for(int j=k; j>=value[i]; j--)
dp[j]=max(dp[j],dp[j-value[i]]+value[i]);//01背包
printf("%d %d\n",sum-dp[k],dp[k]);//输出A B;
}
return 0;
}
/*
2
10 1
20 1
3
10 1
20 2
30 1
*/
相关文章推荐
- Nightmare(搜索)
- SPBF(队列优化的Bellman-Foord)
- 第k大值01背包问题
- Interesting Punch-Bowl(优先队列)
- 文件夹病毒清理方法
- 区间的最大重叠度(会议安排问题)
- A Mini Locomotive(动态规划 01)
- hdu-5750 Dertouzos(数论)
- 01背包 和 完全背包 详解
- Square(强大的剪枝)
- 继续畅通工程(kruskal prim)
- 最小生成树问题(Kruskal 算法)(克鲁斯卡尔)
- Dividing (多重背包 搜索)
- Jack Straws(判断线段是否相交 + 并查集)
- 欧拉函数
- Prime Ring Problem(搜索)
- Cleaning Shifts(区间覆盖)
- Piggy-Bank(完全背包)
- 丑数
- 放苹果(动态规划)