母函数的具体介绍见博客: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,可兼做模板:
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 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利用母函数求解的代码:
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 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; }
|