HDU 2082 找单词

说明:测试样例,题目告诉我们有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;
  }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值