【杭电100题】【母函数/DP】2082 找单词

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2082

本以为和dfs那道一样,但超时了
照着模板用母函数做,要记得初始化

参考资料:
1、母函数原理+模板代码
2、母函数讲解+AC代码+注释
3、母函数模板代码+母函数AC代码+DP AC代码

#include <iostream>
#include <string.h>

using namespace std;

const int maxn=51;      //多项式最大指数
int c1[maxn];           //保存【当前结果多项式】
int c2[maxn];           //保存【中间变量多项式】

int main()
{
    int n;
    cin>>n;
    int num[27];
    while(n--)
    {
        int i;
        for(i=1; i<=26; i++)
            cin>>num[i];

        memset(c1, 0, sizeof(c1));
        memset(c2, 0, sizeof(c2));

        //1.初始化第一个多项式
        for(i=1; i<=26; i++)
        {
            if(num[i]>0)    //选择第一个不为0的多项式
            {
                for(int j=0; j<=num[i]; j++)
                {
                    if(i*j>50)      //此处勿忘
                        break;
                    else
                        c1[i*j]=1;
                }
                break;
            }
        }


        //2.计算所有多项式的乘积(即母函数)
        for(i=i+1; i<=26; i++)
        {
            //2.1 计算【当前结果多项式】与【第i个多项式】的乘积
            for(int j=0; j<maxn; j++)
            {
                //确保【当前结果多项式】的【指数为j的项】的系数不为0
                if(c1[j])
                {
                    //计算【指数为j的项】与【第i个多项式】的乘积
                    for(int k=0; k<=num[i]; k++)
                    {
                        //计算【指数为j的项】与【第i个多项式】的乘积

                        if(j+k*i>50)    //确保该乘积的系数在范围内
                            break;

                        c2[j+k*i]+=c1[j];//用c2记录该乘积的系数
                    }
                }
            }

            //2.2 更新【当前结果多项式c1】,清空【中间变量多项式c2】
            for(int j=0; j<maxn; j++)
            {
                c1[j]=c2[j];
                c2[j]=0;
            }
        }

        //3.从母函数中找出我们要的组合数
        int cnt=0;
        for(i=1; i<maxn; i++)
        {
            cnt+=c1[i];
        }

        cout<<cnt<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41727666/article/details/88425843
今日推荐