HDU 2082找单词——————最简单的母函数 :)

找单词

Problem Description
假设有x1个字母A, x2个字母B,… x26个字母Z,同时假设字母A的价值为1,字母B的价值为2,… 字母Z的价值为26。那么,对于给定的字母,可以找到多少价值<=50的单词呢?单词的价值就是组成一个单词的所有字母的价值之和,比如,单词ACM的价值是1+3+14=18,单词HDU的价值是8+4+21=33。(组成的单词与排列顺序无关,比如ACM与CMA认为是同一个单词)。

Input
输入首先是一个整数N,代表测试实例的个数。
然后包括N行数据,每行包括26个<=20的整数x1,x2,…x26.

Output
对于每个测试实例,请输出能找到的总价值<=50的单词数,每个实例的输出占一行。

Sample Input
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

Sample Output
7
379297


母函数的基本操作
假设用x表示字母,x的指数表示总价值
可以得到
x 1 x_1 x1个字母 A A A 可以用多项式 : 1 + x 1 + x 2 + ⋯ :\quad1+x^1+x^2+\cdots :1+x1+x2+
x 2 x_2 x2个字母 B B B 可以用多项式 : 1 + x 2 + x 4 + ⋯ :\quad1+x^2+x^4+\cdots :1+x2+x4+
x 3 x_3 x3个字母 C C C 可以用多项式 : 1 + x 3 + x 6 + ⋯ :\quad1+x^3+x^6+\cdots :1+x3+x6+
⋮ ⋮ \qquad\vdots \\ \qquad\vdots
x 26 x_{26} x26个字母 Z Z Z 可以用多项式 : 1 + x 1 + x 26 + ⋯ :\quad1+x^1+x^{26}+\cdots :1+x1+x26+

构造母函数如下:
G ( x ) = ( 1 + x 1 + ⋯ &ThinSpace; ) ( 1 + x 2 + ⋯ &ThinSpace; ) ⋯ ( 1 + x 26 + ⋯ &ThinSpace; ) G(x) =(1+x^1+\cdots)(1+x^2+\cdots)\cdots(1+x^{26}+\cdots) G(x)=(1+x1+)(1+x2+)(1+x26+)

可得到:
G ( x ) = 1 + c 1 x + c 2 x 2 + ⋯ \Large G(x) = 1+c_1x+c_2x^2+\cdots G(x)=1+c1x+c2x2+

其中 c i ∗ x i c_i*x^{i} cixii是价值, c i c_i ci是方案数

我们只需要统计 ∑ i = 1 50   c i \sum_{i=1}^{50}\ c_i i=150 ci就能得出结果

#include<bits/stdc++.h>
using namespace std;
int C1[55];//系数;
int C2[55];//暂时存放
 
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		memset(C1,0,sizeof(C1));
		memset(C2,0,sizeof(C2));
		int num;C1[0]=1;
		for(int i=1;i<=26;++i)
		{
			scanf("%d",&num);
			if(!num)	continue;
			for(int j=0;j<51;++j)
				for(int k=0;k<=num&&k*i+j<51;++k)//因为只要前五十项的系数... 
					C2[k*i+j] += C1[j];//对于每一个x^(k*i+1)项,它的系数都要加上前面与它相乘x^j项的系数 
			memcpy(C1,C2,sizeof(C2));//将C2赋值给C1 
			memset(C2,0,sizeof(C2));				
		}	 
		int ans = 0;
		for(int i=1;i<51;++i)	ans += C1[i];
		printf("%d\n",ans);			
	} 
	return 0;
 } 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值