Problem Description

Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.
The splitting is absolutely a big event in HDU! At the same time, it is a trouble thing too. All facilities must go halves. First, all facilities are assessed, and two facilities are thought to be same if they have the same value. It is assumed that there is N (0<N<1000) kinds of facilities (different value, different kinds).

Input

Input contains multiple test cases. Each test case starts with a number N (0 < N <= 50 -- the total number of different facilities). The next N lines contain an integer V (0<V<=50 --value of facility) and an integer M (0<M<=100 --corresponding number of the facilities) each. You can assume that all V are different.
A test case starting with a negative integer terminates input and this test case is not to be processed.

Output

For each case, print one line containing two integers A and B which denote the value of Computer College and Software College will get respectively. A and B should be as equal as possible. At the same time, you should guarantee that A is not less than B.

Sample Input

2
10 1
20 1
3
10 1
20 2
30 1
-1

Sample Output

20 10
40 40
解题思路:典型的多重背包问题,由于题目给的时限比较多,果断转化成01背包暴力过了233。题意是:尽量使得A,B两者分得的价值接近相等(两者价值总和为所有设施设备的总价值),并且A分得的价值不小于B分得的价值,那么问题就可以转化成不超过总价值的一半(视为背包的容量△(已经是确定值))下,挑选若干件物品装入背包后,使得总价值最大,即为B得到的最大价值,A得到的价值为sum-dp[sum/2]。最坏的时间复杂度大约为6e8级别,可见测试数据挺水的。
AC代码一(717ms):
 #include<bits/stdc++.h>
using namespace std;
int n,v,m,num,sum,vi[],dp[];//最大价值的一半:50*100*50/2=125000,数组开大一点即可
int main(){
while(~scanf("%d",&n)&&n>=){
memset(vi,,sizeof(vi));
memset(dp,,sizeof(dp));
num=sum=;//sum记录总价,num记录物品的总数
while(n--){
scanf("%d%d",&v,&m);
while(m--){//有m个价值相等的物品
vi[num++]=v;//把m个物品看成m件不同的物品,多重背包转化成01背包
sum+=v;//累加价值
}
}
for(int i=;i<num;++i)
for(int j=sum/;j>=vi[i];--j)
dp[j]=max(dp[j],dp[j-vi[i]]+vi[i]);
printf("%d %d\n",sum-dp[sum/],dp[sum/]);//dp[sum/2]比较小即为B,因为求解过程是让max尽量靠近sum/2
}
return ;
}

AC代码二(78ms):

 #include<bits/stdc++.h>
using namespace std;
int t,W,n,tol,value[],num[],dp[];
void ZeroOnePack(int w,int v){//01背包
for(int j=W;j>=w;--j)
dp[j]=max(dp[j],dp[j-w]+v);
}
void CompletePack(int w,int v){//完全背包
for(int j=w;j<=W;++j)
dp[j]=max(dp[j],dp[j-w]+v);
}
void MultiplePack(int w,int v,int num){//多重背包
if(w*num>=W)CompletePack(w,v);
else{
for(int k=;k<=num;k<<=){//二进制思想
ZeroOnePack(w*k,v*k);
num-=k;
}
if(num>)ZeroOnePack(w*num,v*num);
}
}
int main(){
while(~scanf("%d",&n)&&n>=){
memset(dp,,sizeof(dp));tol=W=;
for(int i=;i<=n;++i){
scanf("%d%d",&value[i],&num[i]);
tol+=value[i]*num[i];
}
W=tol/;
for(int i=;i<=n;++i)
MultiplePack(value[i],value[i],num[i]);
printf("%d %d\n",tol-dp[W],dp[W]);
}
return ;
}

AC代码三(62ms):单调队列优化

 #include<bits/stdc++.h>
using namespace std;
int W,n,tol,val[],num[],dp[];
struct node{
int k,v;
node(int x,int y):k(x),v(y){}
};
deque<node> dq;
void SingleDeque(int w,int v,int cnt){
for(int r=;r<w;++r){//r=j%w
dq.clear();
for(int t=;t*w+r<=W;++t){//t=j/w
int tmp=dp[t*w+r]-t*v;
while(!dq.empty()&&tmp>=dq.back().v)dq.pop_back();
dq.push_back(node(t,tmp));
while(!dq.empty()&&(t-cnt>dq.front().k))dq.pop_front();
dp[t*w+r]=dq.front().v+t*v;
}
}
}
int main(){
while(~scanf("%d",&n)&&n>=){
tol=W=;memset(dp,,sizeof(dp));
for(int i=;i<=n;++i)
scanf("%d%d",&val[i],&num[i]),tol+=val[i]*num[i];
W=tol/;
for(int i=;i<=n;i++){
num[i]=min(num[i],W/val[i]);
SingleDeque(val[i],val[i],num[i]);
}
printf("%d %d\n",tol-dp[W],dp[W]);
}
return ;
}

题解报告:hdu 1171 Big Event in HDU(多重背包)的更多相关文章

  1. HDU 1171 Big Event in HDU 多重背包二进制优化

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Jav ...

  2. HDU 1171 Big Event in HDU (多重背包变形)

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. 组合数学 - 母函数的变形 --- hdu 1171:Big Event in HDU

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  4. HDU 1171 Big Event in HDU (多重背包)

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. hdu 1171 Big Event in HDU(母函数)

    链接:hdu 1171 题意:这题能够理解为n种物品,每种物品的价值和数量已知,现要将总物品分为A,B两部分, 使得A,B的价值尽可能相等,且A>=B,求A,B的价值分别为多少 分析:这题能够用 ...

  6. 【01背包】HDU 1171 Big Event in HDU

    Problem Description Nowadays, we all know that Computer College is the biggest department in HDU. Bu ...

  7. HDU 1171 Big Event in HDU dp背包

    Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s ...

  8. HDU 1171 Big Event in HDU 母函数

    欢迎参加——BestCoder周年纪念赛(高质量题目+多重奖励) Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory ...

  9. HDU 1171 Big Event in HDU【01背包/求两堆数分别求和以后的差最小】

    Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...

随机推荐

  1. Shell 脚本小试牛刀(5) -- 超便捷脚本之高速ssh 登录其它主机

    假设你也是以Linux 为工作环境的童鞋,那么此文真是捷报!由于我的学习/工作中(特别是近期玩耍树莓派)常常会使用到ssh 登录其它主机,而每次使用ssh 登录都须要输入老长一大串让我非常烦.所以我写 ...

  2. Centos 5.11 samba

    1.使用yum安装samba,添加samba user yum install samba samba-client samba-swatuseradd smbuser -m             ...

  3. UI 经常用法总结之--- UILabel UITextField (不断更新中)

    UILabel : UIView <NSCoding> 1.创建一个UILabel对象 UILabel *label = [[UILabel alloc]initWithFrame:CGR ...

  4. HDU 5303 Delicious Apples (贪心 枚举 好题)

    Delicious Apples Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  5. vue自定义轮播图组件 swiper

    1.banner 组件 components/Banner.vue <!-- 轮播图 组件 --> <template> <div class="swiper- ...

  6. C语言 字符串操作 笔记

    /* C语言字符串的操作笔记 使用代码和注释结合方式记录 */ # include <stdio.h> # include <string.h> int main(void) ...

  7. spinlock in linux kernel

    spinlock in linux kernel 作为一种锁机制, spinlock可以制造一段临界区, 同一时刻只有一个线程能进入这个临界区, 从而达到保护数据的目的. semaphore, mut ...

  8. Android开发系列(二十七):使用ProgressDialog创建进度对话框

    进度对话框在寻常的应用中非经常见,比方下载的时候,打开页面的时候.转移文件等等.有环形的.有长条形的. 基本就这两种 创建进度对话框的两种方式: 1.创建ProgressDialog实例,然后调用Pr ...

  9. npm, webpack, vue-cli, vue-x, axios

    1,什么是node.js,以及npm 简单的来说Node.js就是运行在服务端的JavaScript,是基于Chrome V8引擎的.npm是Node.js包的管理工具. 2,npm的安装和更新 No ...

  10. SpringMVC_基本配置 --跟海涛学SpringMVC(和自己在项目中的实际使用的对比)

    ☆依赖jar包: 1.Spring框架jar 包: 为了简单,将spring-framework-3.1.1.RELEASE-with-docs.zip/dist/下的所有jar包拷贝到项目的WEB- ...