上网搜了一下这道题的解法,主要有两个方法,一种是采用母函数的方法,一种是采用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. 使用WebDriver遇到的那些坑(转)

    http://www.huangbowen.net/blog/2013/06/25/practice-of-webdriver/ 在做web项目的自动化端到端测试时主要使用的是Selenium Web ...

  2. NanoApe Loves Sequence-待解决

    NanoApe Loves Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java ...

  3. PHP---TP框架---添加数据-----有三种方式

    添加数据 添加数据有三种方式: 第一种: <?php namespace Home\Controller;//这个文件的命名空间 use Think\Controller;//use使用哪一个而 ...

  4. OSG 初始化为非全屏窗口

    OSG默认的窗口时全屏的,调试的时候不方便. 在网上看到一段代码,可以非全屏显示 int _tmain(int argc, _TCHAR* argv[]){ osgViewer::Viewer vie ...

  5. 解决java.lang.UnsupportedClassVersionError

    出现java.lang.UnsupportedClassVersionError 错误的原因,是因为我们使用高版本的JDK编译的Java class文件试图在较低版本的JVM上运行,所报的错误. 版本 ...

  6. 【Ubuntu14.04.1】设置开机可以Root用户身份登录

    $ sudo gedit /usr/share/lightdm/lightdm.conf.d/50-ubuntu.conf [SeatDefaults]user-session=ubuntugreet ...

  7. RecyclerView拖拽排序和滑动删除实现

    效果图 如何实现 那么是如何实现的呢?主要就要使用到ItemTouchHelper ,ItemTouchHelper 一个帮助开发人员处理拖拽和滑动删除的实现类,它能够让你非常容易实现侧滑删除.拖拽的 ...

  8. 归并排序的分析与Java实现

    归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作.归并排序算法依赖归并操作.该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.归并排序 ...

  9. device unauthorized & ANDROID_ADB_SERVER_PORT 问题解决

    最近做安卓开发的时候,碰到了如下两个极品问题,刚开始晕头转向,仔细一研究终于解决了: FAQ1: C:\Users\xxx>adb shelladb: Env var ANDROID_ADB_S ...

  10. OpenStack Swift集群部署流程与简单使用

    之前介绍了<OpenStack Swift All In One安装部署流程与简单使用>,那么接下来就说一说Swift集群部署吧. 1. 简介 本文档详细描述了使用两台PC部署一个小型Sw ...