母函数的具体介绍见博客:http://www.wutianqi.com/?p=596
其中第二类的说明中,对于为什么第一个表达式是(1+x^1+x^2+x^3….+x^n),第二个表达式是(1+x^2+x^4+x^6),没有解释清楚,我自己想了一下,做了hdu1389(http://acm.hdu.edu.cn/showproblem.php?pid=1398)这道题,才彻底明白,第一个表达式,指的是,只用价值为1的硬币组成的价值,第二个表达式是只用价值为2的硬币能获得的价值,那么第一个和第二个表达式相乘,就可以获得只有价值为1和2两种硬币组成的价值的情况,且系数表示种类。这样子也就不难理解1389对模板的改变了。
hdu 1389,可兼做模板:
| 12
 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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 
 | /** Author:  xtestw
 * Created Time:  2014/7/8 7:32:31
 * File Name: 1289.cpp
 */
 #include <iostream>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <cmath>
 #include <algorithm>
 #include <string>
 #include <vector>
 #include <stack>
 #include <queue>
 #include <set>
 #include <time.h>
 using namespace std;
 const int maxint = -1u>>1;
 int c1[400],c2[400];
 int main() {
 #ifndef ONLINE_JUDGE
 freopen("f:/in.txt","r",stdin);
 #endif
 int n;
 while (scanf("%d",&n) && n)
 {
 for(int i=0;i<=n;i++)
 {
 c1[i]=1;
 c2[i]=0;
 }
 for(int i=2;i*i<=n;i++)//i*i表示的就是第i个表达式是由价值为i*i的硬币的情况
 {
 for(int j=0;j<=n;j++)
 {
 for(int k=0;k+j<=n;k+=i*i)
 {
 c2[j+k]+=c1[j];
 }
 }
 
 for(int j=0;j<=n;j++)
 {
 c1[j]=c2[j];
 c2[j]=0;
 }
 }
 cout<<c1[n]<<endl;
 }
 return 0;
 }
 
 | 
 hdu 1171利用母函数求解的代码:
| 12
 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
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 
 | /** Author:  xtestw
 * Created Time:  2014/7/8 8:47:03
 * File Name: 1171.cpp
 */
 #include <iostream>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
 #include <cmath>
 #include <algorithm>
 #include <string>
 #include <vector>
 #include <stack>
 #include <queue>
 #include <set>
 #include <time.h>
 using namespace std;
 const int maxint = -1u>>1;
 int c1[300000];
 int c2[300000];
 int v[1000];
 int w[1000];
 int main() {
 #ifndef ONLINE_JUDGE
 freopen("f:/in.txt","r",stdin);
 #endif
 int n;
 while (scanf("%d",&n) && n>0)
 {
 int sum=0;
 for(int i=1;i<=n;i++)
 {
 scanf("%d%d",&v[i],&w[i]);
 sum+=v[i]*w[i];
 }
 memset(c2,0,sizeof(c2));
 memset(c1,0,sizeof(c1));
 for(int i=0;i<=w[1];i++)
 {
 c1[v[1]*i]=1;
 c2[i]=0;
 }
 int max=0;
 for(int i=2;i<=n;i++)
 {
 for(int j=0;j<=sum;j++)
 {
 for(int k=0;k+j<=sum && k<=w[i]*v[i];k+=v[i])
 {
 c2[j+k]+=c1[j];
 }
 }
 for(int j=0;j<sum;j++)
 {
 c1[j]=c2[j];
 c2[j]=0;
 }
 }
 for(int i=sum/2;i>=0;i--)
 {
 if (c1[i])
 {
 cout<<sum-i<<" "<<i<<endl;
 break;
 }
 }
 }
 return 0;
 }
 
 |