找单词
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3015 Accepted Submission(s): 2168
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.
然后包括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这是一道简单的母函数题,不懂母函数的,可以看:http://www.wutianqi.com/?p=596
这里讲的很好很仔细,没入门的也看得懂下面是解释和AC代码:#include<iostream> #include<cstring> const int MAX=100; int c1[MAX];//c1数组是存放系数 ,c1数组的标号是对应的指数,即c1[0]=1那个0就是指数为0的系数为1,而且指数代表就是组成的单词的价值 int c2[MAX];//是中间变量,说白了就是过渡用的,当一个中转站 int num[MAX]; using namespace std; int main() { int n,m,i,j,sum; cin>>n; while(n--) { for(i=1;i<=26;i++) cin>>num[i]; memset(c1,0,sizeof(c1)); memset(c2,0,sizeof(c2)); c1[0]=1;//这里c1[0]赋值为1是因为任何多项式(只要有这多项式)乘指数为0的数后系数是不变的,前面因为初始化都为0,所以只要存在这个多项式乘了c1[0]后系数都是1(存在就是1,不存在也就可能相乘了就还是0了) for(i=1;i<=26;i++)//一共有多少个多项式,即几个多项式相乘 { for(j=0;j<=50;j++)//这里j是指数即与之相乘的指数,最大只能到50,上面说了指数代表单词的价值 { for(m=0;m<=num[i]&&j+m*i<=50;m++)//这里j+m*i是相乘后指数相加 { c2[j+m*i]+=c1[j]; } } for(j=0;j<=50;j++) { c1[j]=c2[j];//把过渡量再赋值给c1 c2[j]=0;//再初始化为0 } } sum=0; for(i=1;i<=50;i++)//把价值1到50全部加起来就是结果了 sum+=c1[i]; cout<<sum<<endl; } return 0; }