今天学习了一下母函数的知识,感觉它像是专门做一类题用的。
推荐一个比较好的入门的母函数博客:http://www.wutianqi.com/?p=596
我写这篇文章的目的,就是为了再次总结一下他写的那个模板,毕竟看了很久才懂的。
这里我以 hdu 1028 这道题为例
这道题目的大致意思是:给你一个正整数N,然后要你求有多少种可以加到N的方式。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define maxn 125
int c1[maxn],c2[maxn];
int main(){
int n;
while(~scanf("%d",&n)){
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=0;i<=n;i++){
c1[i]=1;
c2[i]=0;
}
for(int i=2;i<=n;i++){<span style="white-space:pre"> </span>//i代表的是当前处于第几个括号中,也就是第几个式子
for(int j=0;j<=n;j++){<span style="white-space:pre"> </span>//j代表的是指数
for(int k=0;k+j<=n;k+=i){<span style="white-space:pre"> </span>//k代表的也是指数,注意这里是k+=i,因为对于第i个式子来说它增加的方式是每次都增加i
c2[k+j]+=c1[j];<span style="white-space:pre"> </span>//!!!
}
}
for(int j=0;j<=n;j++){<span style="white-space:pre"> </span>//这里的目的是更新c1,同时把c2清零。
c1[j]=c2[j];
c2[j]=0;
}
}
//for(int i=0;i<=2*n;i++) printf("%d ",c1[i]); puts("");
printf("%d\n",c1[n]);
}
}
这是一道母函数的模板题。
c1数组是用来保存各质量砝码可以组合的数目,c2数组则是为了保存中间的结果。
首先在第一个for中我们对c1数组全部初始化为1,因为第一个括号里面的各项一开始系数均为1。
在我打叹号的地方,我觉得这里的意思是:对于指数为(k+j)的项,它的系数就直接加上c1[j]就好了,因为一开始它的系数为1,然后相乘后系数为c1[j]了,所以直接加上就好。
*我觉得这里也用到了一个贪心的思想,就是因为我们要得到的是n这个数有几种组成方式,所以我们只需要求出n这个指数的系数就好了,对于大于它的可以不用求。
也许理解的并不是很好,希望指教!