【HDU 1059】Dividing(多重背包)

落日映苍穹つ 2022-03-09 00:09 278阅读 0赞

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059

题意:有6种物品,价值分别是1,2,3,4,5,6,每种物品有n[ i ]个,,问是否能将其平分。

思路:分析可知这是一个多重背包问题,为了简化问题,将多重背包转化成0-1背包,另外,还要注意的是,要将n转化成二进制来优化时间复杂度。(任何数都有n=k\_\{1\}2^\{0\}+k\_\{2\}2^\{1\}+k\_\{3\}2^\{2\}+...+k\_\{x\}2^\{y\})例如7(7=1+2+4)个价值为3的物品,就可以将其转化成3个价值分别为3,6,12的物品,这样就可以减少不少时间。

My Code:

  1. #include<iostream>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<algorithm>
  5. using namespace std;
  6. typedef long long ll;
  7. int v[20005],W,f[150000];
  8. int main()
  9. {
  10. int n[10],t = 1;
  11. while(1)
  12. {
  13. W = 0;
  14. int k = 0;
  15. for(int i = 1; i <= 6; i++)
  16. {
  17. cin >> n[i];
  18. W += n[i] *i;
  19. for(int j = 1; j <= n[i]; j = j<<1)///左移一位相当于乘2
  20. {
  21. v[k++] = j*i;///每个的价值等于它的二进制*i
  22. n[i] -= j;
  23. }
  24. if(n[i] != 0) v[k++] = n[i]*i;
  25. }
  26. if(W == 0) break;
  27. printf("Collection #%d:\n",t++);
  28. if(W % 2 != 0)///如果总重量是奇数,必定不能平分
  29. {
  30. printf("Can't be divided.\n\n");
  31. continue;
  32. }
  33. memset(f,0,sizeof(f));///转化成0-1背包,而且其价值=重量
  34. for(int i = 0; i < k; i++)
  35. {
  36. for(int j = W/2; j >= v[i]; j--)
  37. f[j] = max(f[j],f[j-v[i]]+v[i]);
  38. }
  39. if(f[W/2] == W/2) printf("Can be divided.\n\n");
  40. else printf("Can't be divided.\n\n");
  41. }
  42. }

发表评论

表情:
评论列表 (有 0 条评论,278人围观)

还没有评论,来说两句吧...

相关阅读