hdu 1171 (背包或者母函数问题)
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).
A test case starting with a negative integer terminates input and this test case is not to be processed.
Sample Input
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int v[]={};
int f[]={};
int main()
{
int t;
while(cin>>t&&t>)
{
int sum=;
int count=;
memset(v,,sizeof(v));
memset(f,,sizeof(f));
while(t--)
{
int n,m;
cin>>n>>m;
for(int i=;i<m;i++)
{
v[count++]=n;
sum+=n;
}
}
for(int i=;i<count;i++)
{
for(int j=sum/;j>=v[i];j--)
{
f[j]=max(f[j],f[j-v[i]]+v[i]);
}
}
cout<<sum-f[sum/]<<" "<< f[sum/]<<endl;
}
return ;
}
后面上网查了一下,发现了一个什么新概念,母函数的方法用来处理这种有一个或者多个的题目,具体的什么也没怎么看懂,感觉挺复杂的样子,但是这种题相当于一种模板题目,从大佬博客里面抄来的模板。
//为计算结果,b为中间结果。
int a[MAX],b[MAX];
//初始化a
memset(a,,sizeof(a));
a[]=;
for (int i=;i<=;i++)//循环每个因子
{
memset(b,,sizeof(b));
for (int j=n1[i];j<=n2[i]&&j*v[i]<=P;j++)//循环每个因子的每一项
for (int k=;k+j*v[i]<=P;k++)//循环a的每个项
b[k+j*v[i]]+=a[k];//把结果加到对应位
memcpy(a,b,sizeof(b));//b赋值给a
}
P是可能的最大指数。拿钞票组合这题来说,如果要求15元有多少组合,那么P就是15;如果问最小的不能拼出的数值,那么P就是所有钱加起来的和。P有时可以直接省略。
如果n2是无穷,那么第二层循环条件j<=n2[i]可以去掉。
还有一种提高效率的模板2:
用一个last变量记录目前最大的指数,这样只需要在0..last上进行计算。
//初始化a,因为有last,所以这里无需初始化其他位
a[]=;
int last=;
for (int i=;i<K;i++)
{
int last2=min(last+n[i]*v[i],P);//计算下一次的last
memset(b,,sizeof(int)*(last2+));//只清空b[0..last2]
for (int j=n1[i];j<=n2[i]&&j*v[i]<=last2;j++)//这里是last2
for (int k=;k<=last&&k+j*v[i]<=last2;k++)//这里一个是last,一个是last2
b[k+j*v[i]]+=a[k];
memcpy(a,b,sizeof(int)*(last2+));//b赋值给a,只赋值0..last2
last=last2;//更新last
}
而套用模板二ac的本题代码
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 250010
int n,a[MAX],b[MAX],i,j,k,last,last2,v[],m[];
int main()
{
while ((cin>>n)&&n>=)
{
for (i=;i<n;i++)
cin>>v[i]>>m[i];
a[]=;
last=;
for (i=;i<n;i++)
{
last2=last+m[i]*v[i];
memset(b,,sizeof(int)*(last2+));
for (j=;j<=m[i];j++)
for (k=;k<=last;k++)
b[k+j*v[i]]+=a[k];
memcpy(a,b,sizeof(int)*(last2+));
last=last2;
}
for (i=last/;i>=&&a[i]==;i--);
cout<<last-i<<' '<<i<<endl;
}
return ;
}
hdu 1171 (背包或者母函数问题)的更多相关文章
- 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 ...
- HDU 1171 背包
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- hdu 1171 Big Event in HDU(母函数)
链接:hdu 1171 题意:这题能够理解为n种物品,每种物品的价值和数量已知,现要将总物品分为A,B两部分, 使得A,B的价值尽可能相等,且A>=B,求A,B的价值分别为多少 分析:这题能够用 ...
- HDU 1171 Big Event in HDU(01背包)
题目地址:HDU 1171 还是水题. . 普通的01背包.注意数组要开大点啊. ... 代码例如以下: #include <iostream> #include <cstdio&g ...
- Big Event in HDU(HDU1171)可用背包和母函数求解
Big Event in HDU HDU1171 就是求一个简单的背包: 题意:就是给出一系列数,求把他们尽可能分成均匀的两堆 如:2 10 1 20 1 结果是:20 10.才最均匀! 三 ...
- 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 ...
- hdu 01背包汇总(1171+2546+1864+2955。。。
1171 题意比较简单,这道题比较特别的地方是01背包中,每个物体有一个价值有一个重量,比较价值最大,重量受限,这道题是价值受限情况下最大,也就值把01背包中的重量也改成价值. //Problem : ...
- 1171 Big Event in HDU 01背包
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1171 题意:把商品分成两半,如不能均分,尽可能的让两个数相接近.输出结果:两个数字a,b且a>=b. ...
- HDU 1171 01背包
http://acm.hdu.edu.cn/showproblem.php?pid=1171 基础的01背包,求出总值sum,背包体积即为sum/2 #include<stdio.h> # ...
随机推荐
- Docker系列(一):Docker简单介绍
Docker简介: 多语言和框架:支持多语言和框架以及语言框架的扩展机制 多服务:开放的核心服务以及服务的扩展机制 多云和多IaaS技术:支持多种IaaS技术和多云的部署,包括公有云和私有云 Dock ...
- 19.SimLogin_case07
# 模拟登录豆瓣 from urllib.request import urlretrieve import requests from bs4 import BeautifulSoup from o ...
- JavaScript基础的一些小总结
一.js变量 1.变量声明: var 关键字来进行变量声明 变量是弱类型 1.数字 2.小数 3.boolean 4.字符串 4.字符 验证数据类型:1.整数,小数是numbe ...
- view架构
一 Django的视图函数view 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错 ...
- 13-2-return
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Lua 协程和线程区别
协程就是协程,不是线程. CPU执行单位是线程,不是什么协程. 协程,是同步执行,不是并行,只是切了一个上下文了,为你保存原来的上下文而已. 切到第二个协程时,原来的协程处于挂起状态. 这个特指lua ...
- thml粘连布局
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...
- redis笔记_源码_内存分配
文件:zmoalloc.h zmoalloc.c 1.求两个整数的余数 eg: 求_n对sizeof(long)的余数(_n&(sizeof(long)-1)), 性能提升为50%-100% ...
- 数据结构_冒泡排序(python)
1.核心思想:比较两个元素,如果前一个比后一个大则进行交换,经过对每个元素的比较,最后最大的元素被放在在最后位置 操作方法: 外层正常for循环遍历,到n-1位,内层for循环相邻两个数比较大小,小数 ...
- 实时计算Flink on Kubernetes产品模式介绍
Flink产品介绍 目前实时计算的产品已经有两种模式,即共享模式和独享模式.这两种模式都是全托管方式,这种托管方式下用户不需要关心整个集群的运维.其次,共享模式和独享模式使用的都是Blink引擎.这两 ...