上网搜了一下这道题的解法,主要有两个方法,一种是采用母函数的方法,一种是采用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的更多相关文章

  1. hdu ACM Steps Section 1 花式A+B 输入输出格式

    acm与oi很大的一个不同就是在输入格式上.oi往往是单组数据,而acm往往是多组数据,而且题目对数据格式往往各有要求,这8道a+b(吐槽..)涉及到了大量的常用的输入输出格式.https://wen ...

  2. 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 ...

  3. hdu1171 Big Event in HDU 01-背包

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1171 Problem ...

  4. Big Event in HDU(多重背包套用模板)

    http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Java/Othe ...

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

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

  6. HDU-1171 Big Event in HDU

    Big Event in HDU Problem Description Nowadays, we all know that Computer College is the biggest depa ...

  7. 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 ...

  8. Big Event in HDU

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

  9. Big Event in HDU(HDU1171)可用背包和母函数求解

    Big Event in HDU  HDU1171 就是求一个简单的背包: 题意:就是给出一系列数,求把他们尽可能分成均匀的两堆 如:2 10 1 20 1     结果是:20 10.才最均匀! 三 ...

随机推荐

  1. javascript ASCII和Hex互转

    <script> var symbols = " !\"#$%&'()*+,-./0123456789:;<=>?@"; var loAZ ...

  2. java call sap

    1.下载需要的jar,windows用dll,linux用so win下载地址     linux下载地址 win下载地址new 2.环境: windows -> sapjco3.dll放到wi ...

  3. C语言中的break、continue和goto三者的区别与用法

    exit的话是在stdlib的头文件里面定义的,他是的程序退出,正如exit的字面意思一样break的话是终止当前循环继续进行循环后面的语句,但是程序照样还在进行只能while switch for中 ...

  4. Ubuntu下VIM的安装和基本用法

    1.用root账户登录Ubuntu,命令行中输入vim,如果未安装会得到下面的提示: 程序“vim”已包含在下列软件包中:  * vim  * vim-gnome  * vim-tiny  * vim ...

  5. JUC回顾之-ScheduledThreadPoolExecutor底层实现原理和应用

    项目中经常使用定时器,比如每隔一段时间清理下线过期的F码,或者应用timer定期查询MQ在数据库的配置,根据不同version实现配置的实时更新等等.但是timer是存在一些缺陷的,因为Timer在执 ...

  6. Wcf for wp8 创建wcf服务 连接wp8模拟器并显示来自wcf服务的接口信息 (一)

    下载: vs2012 pro for wp8 iis express http://download.microsoft.com/download/B/2/8/B2801FEE-9A60-4AFA-8 ...

  7. To be transfered

    bomb: file format elf64-x86-64 Disassembly of section .init: 0000000000400b38 <_init>: 400b38: ...

  8. loj 1031(区间dp+记忆化搜索)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1031 思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了. ...

  9. PHP文件处理类

    /** * 文件读写类 * 读取时,支持跳过N个/行字符然后再读取M个/行字符 * 支持每次读取时使用回调函数 * * 示例: * $file = new File('a.txt', 'r'); * ...

  10. ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component解决

    第一:先确定一下开发流程是否正确 1.写好servlet组件类 2.写好web.xml文件--向服务器介绍组件 3.发布--就是拷贝 注意:要拷贝包结构,不要只拷贝组件类文件 另外,拷贝的是.clas ...