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
*/

 

posted @ 2018-04-04 15:56  啦啦啦天啦噜  阅读(146)  评论(0编辑  收藏  举报