隐藏
「HDU2082」找单词 - 普通型生成函数 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「HDU2082」找单词 - 普通型生成函数

题目大意

    假设有$x_1$个字母A,$x_2$个字母B,$\ldots$,$x_{26}$个字母Z,同时假设字母A的价值为$1$,字母B的价值为$2$,$\ldots$,字母Z的价值为$26$。那么,对于给定的字母,可以找到多少价值$\le50$的单词呢?单词的价值就是组成一个单词的所有字母的价值之和,比如,单词ACM的价值是$1+3+14=18$,单词HDU的价值是$8+4+21=33$。(组成的单词与排列顺序无关,比如ACMCMA认为是同一个单词)。


题目分析

因为无顺序影响,故考虑使用普通型生成函数。
暴力预处理生成函数,暴力卷积。
如果没事干写FFT也是可以的。


代码

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
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<climits>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}

int now[55],pre[55],a[55];

int main() {
int t=Get_Int();
while(t--) {
memset(now,0,sizeof(now));
memset(pre,0,sizeof(pre));
pre[0]=1;
for(int i=1; i<=26; i++) {
int x=Get_Int();
memset(a,0,sizeof(a));
a[0]=1;
for(int j=0; j<=min(50,i*x); j+=i)a[j]=1;
for(int j=0; j<=50; j++)
for(int k=0; k<=min(i*x,50-j); k++)
now[j+k]+=pre[j]*a[k];
memcpy(pre,now,sizeof(pre));
memset(now,0,sizeof(now));
}
int ans=0;
for(int i=1; i<=50; i++)ans+=pre[i];
printf("%d\n",ans);
}
return 0;
}
姥爷们赏瓶冰阔落吧~