hdu acm steps Big Event in HDU
上网搜了一下这道题的解法,主要有两个方法,一种是采用母函数的方法,一种是采用0/1背包的方法。
先说一下母函数,即生成函数,做个比喻,母函数就是一个多项式前面的系数的一个整体的集合,而子函数就是这个多项式每一项前面的系数。主要用于解决组合问题,类似于钱币的组合问题。利用母函数解题时,首先要写出表达式,通常是多项式的乘积形式,类似于:(x^(v[K]*n1[K])+x^(v[K]*(n1[K]+1))+x^(v[K]*(n1[K]+2))+...+x^(v[K]*n2[K]))。
例如,对于有n种物品,如果第i种物品有ki个,我们可以列式n个项相乘 (x^0+x^1+...x^k1)*(x^0+x^1+...x^k2)*...*(x^0+x^1+...x^kn),每一项表示对于第i件物品,可以有(x^0+x^1+...x^ki)中取法,【注意系数都为1,因为同种物品取i件,它的取法是1】多项相乘:因为取m件物品这件事实要分为对n种物品各取分别取1次【0~ki个】, 是组合计数的乘法原理, x^m 的系数是组合成m件物品的所有方案数
一、母函数解题的核心就是要找到:
k(对应具体问题中物品的种类数)、
v[i](表示该乘积表达式第i个因子的权重,对应于具体问题的每个物品的价值或者权重)、
n1[i](表示该乘积表达式第i个因子的起始系数,对应于具体问题中的每个物品的最少个数,即最少要取多少个)、
n2[i](表示该乘积表达式第i个因子的终止系数,对应于具体问题中的每个物品的最多个数,即最多要取多少个)。
之后迭代计算,并将结果放在一个数组a中。其中a[i]表示权重为i的组合数。
二、母函数对应的具体题型:
主要是普通型母函数,主要用在组合和整数拆分问题上。
关于母函数的百度百科:http://baike.baidu.com/view/2415279.htm
三、模板
先贴一下我收集到的母函数模板:
模板一
//a为计算结果,b为中间结果。
int a[MAX],b[MAX];
//初始化a
memset(a,,sizeof(a));
a[]=;
for (int i=;i<=17;i++)//循环每个因子
{
memset(b,,sizeof(b));
for (int j=n1[i];j<=n2[i]&&j*v[i]<=P;j++)//循环每个因子的每一项 ,p为可能的最大指数
for (int k=;k+j*v[i]<=P;k++)//循环a的每个项
b[k+j*v[i]]+=a[k];//把结果加到对应位
memcpy(a,b,sizeof(b));//b赋值给a
}
有一个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
}
因为刚刚接触到acm,最近做的事简单的背包专题,所以此处仅附上背包的思路和解法:
思路:将背包的容量定为所有物品总价值的一半,然后就是0/1背包问题,dp[half]中存储的就是较小的半份。其中,dp[j]表示选前i间物品时,预算为j时背包中装的最大总价值。
状态转移方程为:dp[j]=max{dp[j],dp[j-f[i].v]+f[i].v};
#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"string.h"
#include"cmath"
#define mx 105
using namespace std;
int dp[];//注意dp数组的大小
struct node
{
int v;
int c;
}f[mx];
bool cmp(const node a,const node b)
{
if(a.v!=b.v) return a.v<b.v;
}
int main()
{
int n,i,j,k;
while(cin>>n,n>)
{
int sum=,half;
for(i=;i<n;i++)
{
cin>>f[i].v>>f[i].c;
sum+=f[i].v*f[i].c;
}
half=sum/;
sort(f,f+n,cmp);
memset(dp,,sizeof(dp));
for(i=;i<n;i++)
{
for(k=;k<=f[i].c;k++)
{
for(j=half;j>=f[i].v;j--)
{
if(dp[j]<dp[j-f[i].v]+f[i].v) dp[j]=dp[j-f[i].v]+f[i].v;
}
}
}
cout<<sum-dp[half]<<' '<<dp[half]<<endl;
}
return ;
}
hdu acm steps Big Event in HDU的更多相关文章
- hdu ACM Steps Section 1 花式A+B 输入输出格式
acm与oi很大的一个不同就是在输入格式上.oi往往是单组数据,而acm往往是多组数据,而且题目对数据格式往往各有要求,这8道a+b(吐槽..)涉及到了大量的常用的输入输出格式.https://wen ...
- 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 ...
- hdu1171 Big Event in HDU 01-背包
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1171 Problem ...
- Big Event in HDU(多重背包套用模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Java/Othe ...
- HDU 1171 Big Event in HDU (多重背包变形)
Big Event in HDU Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- HDU-1171 Big Event in HDU
Big Event in HDU Problem Description Nowadays, we all know that Computer College is the biggest depa ...
- hdu acm 1028 数字拆分Ignatius and the Princess III
Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- Big Event in HDU
Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe ...
- Big Event in HDU(HDU1171)可用背包和母函数求解
Big Event in HDU HDU1171 就是求一个简单的背包: 题意:就是给出一系列数,求把他们尽可能分成均匀的两堆 如:2 10 1 20 1 结果是:20 10.才最均匀! 三 ...
随机推荐
- 17.把字符串转换成整数[atoi]
[题目] 把字符串转换成整数,需要考虑字符串有效性. [代码] C++ Code 123456789101112131415161718192021222324252627282930313233 ...
- 如何让你的scrapy爬虫不再被ban
前面用scrapy编写爬虫抓取了自己博客的内容并保存成json格式的数据(scrapy爬虫成长日记之创建工程-抽取数据-保存为json格式的数据)和写入数据库(scrapy爬虫成长日记之将抓取内容写入 ...
- Java for LeetCode 053 Maximum Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- 【USACO】第一章总结
做了大半个月,终于把第一章做完了 有的题遇到了不小的坎儿,看着网上一群高中生都做得那么好,心理还是有些小郁闷的.不禁感慨我过去的四年真是虚度啊.总结一下第一章学习到的知识吧. ①闰年判断 int is ...
- CodeForces - 416A (判断大于小于等于 模拟题)
Guess a number! Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Sub ...
- NEFU 1151 特殊的质数
特殊的质数 Problem:1151 Time Limit:1000ms Memory Limit:65535K Description 如果一个数是质数,而且他在质数表中的编号也是质数,称为特殊的质 ...
- List对象分组排序算法
场景: List里面的对象是订单的节点,比如我们快递的物流状态,这个是需要有序的,所以需要根据订单号进行分组排序. import java.util.ArrayList; import java.ut ...
- Android中几种定位 方式
介绍的几种定位方式 http://www.cnblogs.com/cuihongyu3503319/p/3863867.html 百度地图api: http://lbsyun.baidu.com/in ...
- GRE学习日志
发现开博客园真的很有督促作用,今天也顺便开个GRE学习日志吧 2015-02-09:单词 2015-02-10:单词 2015-02-11:单词 2015-03-02:阅读 2015-03-04:阅读 ...
- UVA - 10891 Game of Sum 区间DP
题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19461 Game of sum Description This ...