说明:测试样例,题目告诉我们有2组测试数据,其中以第一组为例,有1个A,1个B,1个C,那么可以组成的就是 A, B, C, AB, AC, BC, ABC 。一共7种单词。对于第二种也是类似的。对于这个题目,有两种不一样的思想,一方面,这是一个多重背包的问题,另外一个方面,这是一个母函数的问题。 有兴趣的可以去看看这两个的详细介绍。但是对于程序来说是类似的,有26种物品,每一种物品有num[i]个,背包容量为50,查询,在不超过背包容量为50的情况下,这26种物品有多少种放法。首先对于每一种物品而言,有放一个,两个或者多个,但是都不会超过num[i]个,然后对于每一个物品就只有两种可能,放进去,或者不放进去,对于每一种物品就是放多少个的问题了。我们假设,dp[i][j], 的含义是,有i种物品,重量为j,我们对于每一种物品而言,有多少个我们是不关心的,但是对于每一种物品的放了多少个,我们是关心的。所以在放进去的时候,考虑每一种有多少个,但是放进去了,我们就不考虑了,就好像的是,去买菜,别人问你买了什么菜,你只要回答买了萝卜,白菜就好了,但是你买的时候,是要考虑自己手里的钱,是可以买一个萝卜,还是两个萝卜。因此我们用一个二维数组来保存就好了,如果想要知道买几个萝卜那就是要用三维数组了,如果只问你,有没有买菜,那就是用一维数组就可以了,这里,采用了二维数组,理由就是,比较同时符合多重背包和母函数。
#include <stdio.h>
#include <string.h>
int main()
{
int i, j, k, n, sum, num[27], s[27][51];
scanf("%d",&n);
while(n--)
{
memset(s, 0, sizeof(s));
for(i = 1; i <= 26; i++)
scanf("%d", &num[i]);
for(i = 0; i <= 26; i++)///这里是一定要初始化的。每一个物品不拿的可能有且只有一种情况
s[i][0] = 1;
for(i = 1; i <= 26; i++)
for(j = 1; j <= 50; j++)
for(k = 0; k <= num[i] && j - k * i >= 0; k++)//在添加进去的时候,考虑一下,能不能买,老板有没有那么多的货
s[i][j] += s[i - 1][j - k * i];
for(i = 1, sum = 0; i <= 50; i++)//这里就不用管了
sum += s[26][i];
printf("%d\n",sum);
}
return 0;
}