hdu 2072 单词数(普通型生成函数板子)
题意:中文题,略
思路:一年前过这道题的时候是写的完全背包,当时了解过一点生成函数,后来也了解过一些生成函数,但记性不好,也么没有做过许多关于生成函数的题,就忘了(其实就是没学会),现在重新捡起来,这是一份普通型的生成函数板子,
普通型母函数用于解决多重集的组合问题
指数型母函数用于解决多重集的排列问题。
指数型的生成函数窝会在下一篇博客中给出,这里只附上普通型生成函数,说实话,原理到时懂了,板子还没怎么看懂,(保佑省赛东北赛公费出线)
代码:
#include <set> #include <map> #include <queue> #include <stack> #include <math.h> #include <vector> #include <string> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <algorithm> #define zero(a) fabs(a)<eps #define max( x, y ) ( ((x) > (y)) ? (x) : (y) ) #define min( x, y ) ( ((x) < (y)) ? (x) : (y) ) #define lowbit(x) (x&(-x)) #define debug(a) cerr<<#a<<"=="<<a<<endl typedef long long LL; const double pi=acos(-1.0); const double eps=1e-8; const int inf=0x3f3f3f3f; const LL linf=0x3f3f3f3f3f3f3f3f; using namespace std; LL a[105],b[105]; int main() { int T; scanf("%d",&T); while(T--){ memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); a[0]=1; for(int i=1;i<=26;i++){ int x; scanf("%d",&x); for(int j=0;j<=50;j++){ for(int k=0;k<=x&&(j+k*i<=50);k++){ b[j+k*i]+=a[j]; } } for(int j=0;j<=50;j++){ a[j]=b[j]; b[j]=0; } } LL cnt=0; for(int i=1;i<=50;i++){ cnt+=a[i]; } printf("%lld\n",cnt); } return 0; } /* 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 2 6 2 10 2 2 5 6 1 0 2 7 0 2 2 7 5 10 6 10 2 10 6 1 9 */