母函数解析.docx
- 文档编号:3522427
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:29
- 大小:269.54KB
母函数解析.docx
《母函数解析.docx》由会员分享,可在线阅读,更多相关《母函数解析.docx(29页珍藏版)》请在冰豆网上搜索。
母函数解析
长安大学ACM母函数(Generatingfunction)详解
在数学中,某个序列的母函数(Generatingfunction,又称生成函数)是一种形式幂级数,其每一项的系数可以提供关于这个序列的信息。
使用母函数解决问题的方法称为母函数方法。
母函数可分为很多种,包括普通母函数、指数母函数、L级数、贝尔级数和狄利克雷级数。
对每个序列都可以写出以上每个类型的一个母函数。
构造母函数的目的一般是为了解决某个特定的问题,因此选用何种母函数视乎序列本身的特性和问题的类型。
这里先给出两句话,不懂的可以等看完这篇文章再回过头来看:
1.“把组合问题的加法法则和幂级数的乘幂对应起来”
2.“母函数的思想很简单—就是把离散数列和幂级数一一对应起来,把离散数列间的相互结合关系对应成为幂级数间的运算关系,最后由幂级数形式来确定离散数列的构造.“
我们首先来看下这个多项式乘法:
母函数图
(1)
由此可以看出:
1.x的系数是a1,a2,…an的单个组合的全体。
2.x^2的系数是a1,a2,…a2的两个组合的全体。
………
n.x^n的系数是a1,a2,….an的n个组合的全体(只有1个)。
进一步得到:
母函数图
(2)
母函数的定义
对于序列a0,a1,a2,…构造一函数:
母函数图(3)
称函数G(x)是序列a0,a1,a2,…的母函数。
这里先给出2个例子,等会再结合题目分析:
第一种:
有1克、2克、3克、4克的砝码各一枚,能称出哪几种重量?
每种重量各有几种可能方案?
考虑用母函数来解决这个问题:
我们假设x表示砝码,x的指数表示砝码的重量,这样:
1个1克的砝码可以用函数1+1*x^1表示,
1个2克的砝码可以用函数1+1*x^2表示,
1个3克的砝码可以用函数1+1*x^3表示,
1个4克的砝码可以用函数1+1*x^4表示,
上面这四个式子懂吗?
我们拿1+x^2来说,前面已经说过,x表示砝码,x的指数表示砝码的重量!
初始状态时,这里就是一个质量为2的砝码。
那么前面的1表示什么?
按照上面的理解,1其实应该写为:
1*x^0,即1代表重量为2的砝码数量为0个。
所以这里1+1*x^2=1*x^0+1*x^2,即表示2克的砝码有两种状态,不取或取,不取则为1*x^0,取则为1*x^2
不知道大家理解没,我们这里结合前面那句话:
“把组合问题的加法法则和幂级数的乘幂对应起来“
接着讨论上面的1+x^2,这里x前面的系数有什么意义?
这里的系数表示状态数(方案数)
1+x^2,也就是1*x^0+1*x^2,也就是上面说的不取2克砝码,此时有1种状态;或者取2克砝码,此时也有1种状态。
(分析!
)
所以,前面说的那句话的意义大家可以理解了吧?
几种砝码的组合可以称重的情况,可以用以上几个函数的乘积表示:
(1+x)(1+x^2)(1+x^3)(1+x^4)
=(1+x+x^2+x^4)(1+x^3+^4+x^7)
=1+x+x^2+2*x^3+2*x^4+2*x^5+2*x^6+2*x^7+x^8+x^9+x^10
从上面的函数知道:
可称出从1克到10克,系数便是方案数。
(!
!
!
经典!
!
!
)
例如右端有2^x^5项,即称出5克的方案有2种:
5=3+2=4+1;同样,6=1+2+3=4+2;10=1+2+3+4。
故称出6克的方案数有2种,称出10克的方案数有1种。
接着上面,接下来是第二种情况:
第二种:
求用1分、2分、3分的邮票贴出不同数值的方案数:
大家把这种情况和第一种比较有何区别?
第一种每种是一个,而这里每种是无限的。
母函数图(4)
以展开后的x^4为例,其系数为4,即4拆分成1、2、3之和的拆分方案数为4;
即:
4=1+1+1+1=1+1+2=1+3=2+2
这里再引出两个概念"整数拆分"和"拆分数":
所谓整数拆分即把整数分解成若干整数的和(相当于把n个无区别的球放到n个无标志的盒子,盒子允许空,也允许放多于一个球)。
整数拆分成若干整数的和,办法不一,不同拆分法的总数叫做拆分数。
现在以上面的第二种情况每种种类个数无限为例,给出模板:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include
usingnamespacestd;
//Author:
TankyWoo
//
constint_max=10001;
//c1是保存各项质量砝码可以组合的数目
//c2是中间量,保存没一次的情况
intc1[_max],c2[_max];
intmain()
{//intn,i,j,k;
intnNum;//
inti,j,k;
while(cin>>nNum)
{
for(i=0;i<=nNum;++i)//----①
{
c1[i]=1;
c2[i]=0;
}
for(i=2;i<=nNum;++i)//-----②
{
for(j=0;j<=nNum;++j)//-----③
for(k=0;k+j<=nNum;k+=i)//----④
{
c2[j+k]+=c1[j];
}
for(j=0;j<=nNum;++j)//----⑤
{
c1[j]=c2[j];
c2[j]=0;
}
}
cout< } return0; } 我们来解释下上面标志的各个地方: ① 、首先对c1初始化,由第一个表达式(1+x+x^2+..x^n)初始化,把质量从0到n的所有砝码都初始化为1. ② 、i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。 ③、j从0到n遍历,这里j就是(前面i個表达式累乘的表达式)里第j个变量,(这里感谢一下seagg朋友给我指出的错误,大家可以看下留言处的讨论)。 如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的系数,i=2执行完之后变为 (1+x+x^2+x^3)(1+x^3),这时候j应该指示的是合并后的第一个括号的四个变量的系数。 ④、k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。 ⑤ 、把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的。 IgnatiusandthePrincessIII TimeLimit: 2000/1000ms(Java/Other) MemoryLimit: 65536/32768K(Java/Other) TotalSubmission(s): 1 AcceptedSubmission(s): 1 ProblemDescription "Well,itseemsthefirstproblemistooeasy.Iwillletyouknowhowfoolishyouarelater."feng5166says. "Thesecondproblemis,givenanpositiveintegerN,wedefineanequationlikethis: N=a[1]+a[2]+a[3]+...+a[m]; a[i]>0,1<=m<=N; MyquestionishowmanydifferentequationsyoucanfindforagivenN. Forexample,assumeNis4,wecanfind: 4=4; 4=3+1; 4=2+2; 4=2+1+1; 4=1+1+1+1; sotheresultis5whenNis4.Notethat"4=3+1"and"4=1+3"isthesameinthisproblem.Now,youdoit! " Input Theinputcontainsseveraltestcases.EachtestcasecontainsapositiveintegerN(1<=N<=120)whichismentionedabove.Theinputisterminatedbytheendoffile. Output Foreachtestcase,youhavetooutputalinecontainsanintegerPwhichindicatethedifferentequationsyouhavefound. SampleInput 4 10 20 SampleOutput 5 42 627 Author Ignatius.L //1028 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include usingnamespacestd; constint_max=10001; //c1是保存各项可以组合的数目 //c2是中间量,保存没一次的情况 intc1[_max],c2[_max]; intmain() {//intn,i,j,k; intnNum;// inti,j,k; while(cin>>nNum) { for(i=0;i<=nNum;++i)//----① { c1[i]=1; c2[i]=0; } for(i=2;i<=nNum;++i)//-----② { for(j=0;j<=nNum;++j)//-----③ for(k=0;k+j<=nNum;k+=i)//----④ { c2[j+k]+=c1[j]; } for(j=0;j<=nNum;++j)//----⑤ { c1[j]=c2[j]; c2[j]=0; } } cout< } return0; } 我们来解释下上面标志的各个地方: ① 、首先对c1初始化,由第一个表达式(1+x+x^2+..x^n)初始化,把质量从0到n的所有砝码都初始化为1. ② 、i从2到n遍历,这里i就是指第i个表达式,上面给出的第二种母函数关系式里,每一个括号括起来的就是一个表达式。 ③、j从0到n遍历,这里j就是(前面i個表达式累乘的表达式)里第j个变量,(这里感谢一下seagg朋友给我指出的错误,大家可以看下留言处的讨论)。 如(1+x)(1+x^2)(1+x^3),j先指示的是1和x的系数,i=2执行完之后变为 (1+x+x^2+x^3)(1+x^3),这时候j应该指示的是合并后的第一个括号的四个变量的系数。 ④、k表示的是第j个指数,所以k每次增i(因为第i个表达式的增量是i)。 ⑤ 、把c2的值赋给c1,而把c2初始化为0,因为c2每次是从一个表达式中开始的。 Dp解法: 解法: 动态规划,n[i][j]表示数i由<=j的数组成的不同数目,那么i==j时n[i][j]=1+n[i][j-1],i>j时n[i][j]=n[i][j-1]+n[i-j][j](n[i-j][j]是保证shui中至少有一个j),i 代码: #include #include int main() { int i,j,k,a,n[130][130]; for(i=0;i<130;i++)n[i][1]=n[1][i]=1; for(i=2;i<130;i++) { for(j=2;j<130;j++) { if(i>j)n[i][j]=n[i][j-1]+n[i-j][j]; elseif(i==j)n[i][j]=1+n[i][j-1]; else n[i][j]=n[i][i]; } } while(scanf("%d",&a)! =EOF) { printf("%d\n",n[a][a]); } return0; } HoldingBin-LadenCaptive! TimeLimit: 2000/1000ms(Java/Other) MemoryLimit: 65536/32768K(Java/Other) TotalSubmission(s): 1 AcceptedSubmission(s): 1 ProblemDescription WeallknowthatBin-Ladenisanotoriousterrorist,andhehasdisappearedforalongtime.Butrecently,itisreportedthathehidesinHangZhouofChina! “Oh,God! Howterrible! ” Don’tbesoafraid,guys.AlthoughhehidesinacaveofHangZhou,hedaresnottogoout.Ladenissoboredrecentyearsthatheflinghimselfintosomemathproblems,andhesaidthatifanyonecansolvehisproblem,hewillgivehimselfup! Ha-ha! Obviously,Ladenistooproudofhisintelligence! But,whatishisproblem? “GivensomeChineseCoins(硬币)(threekinds--1,2,5),andtheirnumberisnum_1,num_2andnum_5respectively,pleaseoutputtheminimumvaluethatyoucannotpaywithgivencoins.” You,superACMer,shouldsolvetheproblemeasily,anddon’tforgettotake$25000000fromBush! Input Inputcontainsmultipletestcases.Eachtestcasecontains3positiveintegersnum_1,num_2andnum_5(0<=num_i<=1000).Atestcasecontaining000terminatestheinputandthistestcaseisnottobeprocessed. Output Outputtheminimumpositivevaluethatonecannotpaywithgivencoins,onelineforonecase. SampleInput 113 000 SampleOutput 4 Author lcy //1085 母函数: Y=(1+x^2+x^3+x^4…+x^n1*1)*(1+x^2+x^4+x^6…x^n2*2)*(1+x^5+x^10+…x^n3*5) #include"stdio.h" #include"string.h" intmain() {intnum_1,num_2,num_5,sum,i,j,k; //用数组a[1……4]和b[1……4]]分别储存钱数和钱的种类 Inta[4]; Intb[4]; intc1[8001],c2[8001]; while(scanf("%d%d%d",&num_1,&num_2,&num_5)! =EOF&&(num_1+num_2+num_5)! =0) { memset(c1,0,sizeof(c1));//初始化C1 memset(c2,0,sizeof(c2));//初始化C2 sum=num_1+2*num_2+5*num_5;//求出可表示的最大值为后面遍历数打基础 c1[0]=1;//初始化数组 a[1]=num_1; a[2]=num_2; a[3]=num_5; b[1]=1; b[2]=2; b[3]=5; for(i=1;i<=3;i++) {for(j=0;j<=sum;j++) { for(k=0;k+j<=sum&&k<=b[i]*a[i];k+=b[i])//注意与前一题的区别和数组a,b的使用好处 { c2[k+j]+=c1[j]; } } for(j=0;j<=sum;j++) { c1[j]=c2[j]; c2[j]=0; } } intp; for(p=0;p<=sum;p++) if(c1[p]==0)break;//找出第一个不能别表示的数 printf("%d\n",p); } return0; } 找出规律,更简单的方法: #include intmain() { intnum_1,num_2,num_3; while(scanf("%d%d%d",&num_1,&num_2,&num_3),num_1+num_2+num_3) { if(num_1==0) printf("1\n"); elseif(2*num_2+num_1<4) printf("%dn",2*num_2+num_1+1); else printf("%dn",5*num_3+2*num_2+num_1+1); } return0; } BigEventinHDU TimeLimit: 10000/5000ms(Java/Other) MemoryLimit: 65536/32768K(Java/Other) TotalSubmission(s): 1 AcceptedSubmission(s): 1 ProblemDescription Nowadays,weallknowthatComputerCollegeisthebiggestdepartmentinHDU.But,maybeyoudon'tknowthatComputerCollegehadeverbeensplitintoComputerCollegeandSoftwareCollegein2002. ThesplittingisabsolutelyabigeventinHDU! Atthesametime,itisatroublethingtoo.Allfacilitiesmustgohalves.First,allfacilitiesareassessed,andtwofacilitiesarethoughttobesameiftheyhavethesamevalue.ItisassumedthatthereisN(0 Input Inputcontainsmultipletestcases.EachtestcasestartswithanumberN(0 Atestcasestartingwithanegativeintegerterminatesinputandthistestcaseisnottobeprocessed. Output Foreachcase,printonelinecontainingtwointegersAandBwhichdenotethevalueofComputerCollegeandSoftwareCollegewillgetrespectively.AandBshouldbeasequalaspossible.Atthesametime
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 函数 解析