代码
#include <iostream>
#include <cstring>
using namespace std;
const int MAX = 51; //本题要找的是价值<=50的单词数,因此最大数组长度设为51
const int MAXVALUE = 26; //单个字母的最大价值,也就是母函数计算时每个多项式的选1个时的最大间隔次方数,本题是26(eg:字母Z的价值间隔最大,为1+x^26+x^52+...,26为最大间隔)
int a[MAX]; //保存每一轮结束后的结果
int b[MAX]; //保存当前轮对应的系数
int c[MAX]; //保存当前轮的结果
void init(int m, int n, int s[]) { //m:面额/价值,n:个数 s:系数数组 eg:价值为2的有3个,m=2,n=3
for(int j=0; j<MAX; j++) {
if(j%m==0 && j<=m*n) {
s[j] = 1;
} else {
s[j] = 0;
}
}
}
void process() { //模拟母函数的手动处理过程
memcpy(c, a, sizeof(a));
for(int i=1; i<MAX; i++) {
if(b[i]) {
for(int j=0; j<MAX; j++) {
if(i+j<MAX) {
c[i+j] += a[j];
}
}
}
}
memcpy(a, c, sizeof(c));
}
int main() {
int N;
cin>>N;
for(int i=0; i<N; i++) {
memset(a, 0, sizeof(a));
//初始化,价值为1的
int t;
cin>>t; //输入价值为1的单词个数
init(1, t, a);
for(int j=2; j<=MAXVALUE; j++) {
int tmp;
cin>>tmp; //输入价值为j的单词的个数
init(j, tmp, b);
process();
}
int sum = 0;
for(int j=1; j<MAX; j++) {
sum += a[j];
}
cout<<sum<<endl;
}
return 0;
}
注解
1、本题是母函数的模板题。类似于2079
2、母函数的题目,关键要分清楚求的是x多少次方的系数,且有多少种不同价值的硬币(本题中为字母),每种的个数为多少。然后套用模板即可。
3、本题的模板,其实就是手动模拟母函数系数的计算过程。