hdoj 3732 Ahui Writes Word (多重背包)

举报
xindoo 发表于 2022/04/15 22:44:35 2022/04/15
【摘要】       之前在做背包的题目时看到了这道题,一看,大喜,这不是裸裸的01背包吗!!  然后华丽丽的超时,相信很多人也和我一样没有考虑到数据量的大小。       时隔多日,回过头来看这道题,依旧毫无头绪。。。。不过相比之前,我看到了更多细节。 &nbsp...

      之前在做背包的题目时看到了这道题,一看,大喜,这不是裸裸的01背包吗!!  然后华丽丽的超时,相信很多人也和我一样没有考虑到数据量的大小。

      时隔多日,回过头来看这道题,依旧毫无头绪。。。。不过相比之前,我看到了更多细节。

      来看题目吧,可能有100000个单词,然后只有1000ms,但看包的大小,有10000,这样只能允许nlog(n)的算法,还有,每个单词的价值和花费都很小(不大于十),如果不考虑单词的不同,只考虑价值和花费只有最多100种东西,但如果把这些按多重背包的方法来计算依旧会超时,很容易想到和之前01背包的时间复杂度是一样的。

      还记得多重背包可以转换为01背包吗??我们不妨把这些物品进行打包,把每种物品分别1个、2个、4个…………(2^k)个进行打包,如果不足2^k个则单独打包,然后把每一包看做一件物品,继续使用01背包的方法进行计算,这样我们就把原来O(nc)的时间复杂度降到了O(clogn)。




  
  1. //hdoj 3732
  2. //2013-08-10-16.53
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <algorithm>
  6. using namespace std;
  7. int dp[10005];
  8. int vc[11][11];
  9. int w[10005];
  10. int v[10005];
  11. int main()
  12. {
  13. int n, c;
  14. char s[100];
  15. while (scanf("%d %d", &n, &c) != EOF)
  16. {
  17. int a, b;
  18. memset(dp, 0, sizeof(dp));
  19. memset(vc, 0 ,sizeof(vc));
  20. for (int i = 1; i <= n; i++)
  21. {
  22. scanf("%s %d %d", &s, &a, &b);
  23. vc[a][b]++;
  24. }
  25. int cnt = 1;
  26. for (int i = 1; i <= 10; i++)
  27. {
  28. for (int j = 1; j <= 10; j++)
  29. {
  30. if (vc[i][j])
  31. {
  32. int tmp = 1;
  33. while (vc[i][j] > tmp)
  34. {
  35. w[cnt] = tmp*j;
  36. v[cnt] = tmp*i;
  37. vc[i][j] -= tmp;
  38. cnt++;
  39. tmp <<= 1;
  40. }
  41. w[cnt] = j*vc[i][j];
  42. v[cnt] = i*vc[i][j];
  43. cnt++;
  44. }
  45. }
  46. }
  47. for (int i = 1; i < cnt; i++)
  48. {
  49. for (int j = c; j >= w[i]; j--)
  50. dp[j] = max(dp[j], dp[j-w[i]] + v[i]);
  51. }
  52. printf("%d\n", dp[c]);
  53. }
  54. return 0;
  55. }


文章来源: xindoo.blog.csdn.net,作者:xindoo,版权归原作者所有,如需转载,请联系作者。

原文链接:xindoo.blog.csdn.net/article/details/9933741

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。