UVa 812 - Trade on Verweggistan(贪心)

题意

有N个作坊,每个作坊都有一叠酒(我就当成酒了)

如果要买第i个的话,必须买下上面的所有酒。

酒的出售价是10元。

现在有个商人要买酒,求最大利润和达到最大利润的时候买的酒的数量。如果有多解,每个都输出。如果大于10,输出前十个。

思路

看网上都说是DP?我怎么觉得是贪心。

有点类似于有依赖关系的背包。

  1. 如何得到最大利润?

分别计算出每个作坊所能达到的最大利润,然后把所有正的利润加起来就行。

  1. 如何计算达到最大利润时候的数量?

在求出每个作坊的最大利润的时候,扫描一遍数组,如果当前利润i和最大利润一样,就把i存到一个数组里。最后汇总即可。

总体的思路就是这样,还有一些小的东西。

在汇总数量的时候,一开始我不知道怎么办。

比如说,第一个在达到最大利润的时候,数量可以是2 3 
第二个,3 4

那么总的数量就是 5 6 7. 然后这个结果还要作为中间结果,和下面的进行累加。然后我就不知道这个结果要存在哪里。。

后来YY了一下,开了两个数组,先存到数组A,然后存到数组B。。。轮流存╮(╯▽╰)╭

因为可能有重复的,用了unique。

还有当最大利润为0的时候,要加入0.因为可以不选。

就是这样。代码感觉不太优雅,因为有很多重复的地方。仅供参考

代码

  
  
  
  
  1. #include <cstdio>
  2. #include <stack>
  3. #include <set>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <queue>
  8. #include <functional>
  9. #include <cstring>
  10. #include <algorithm>
  11. #include <cctype>
  12. #include <ctime>
  13. #include <cstdlib>
  14. #include <fstream>
  15. #include <string>
  16. #include <sstream>
  17. #include <map>
  18. #include <cmath>
  19. #define LL long long
  20. #define Lowbit(x) ((x) & (-x))
  21. #define MP(a, b) make_pair(a, b)
  22. #define MS(arr, num) memset(arr, num, sizeof(arr))
  23. #define PB push_back
  24. #define F first
  25. #define S second
  26. #define ROP freopen("input.txt", "r", stdin);
  27. #define MID(a, b) (a + ((b - a) >> 1))
  28. #define LC rt << 1, l, mid
  29. #define RC rt << 1|1, mid + 1, r
  30. #define LRT rt << 1
  31. #define RRT rt << 1|1
  32. #define BitCount(x) __builtin_popcount(x)
  33. const double PI = acos(-1.0);
  34. const int INF = 0x3f3f3f3f;
  35. using namespace std;
  36. const int MAXN = 2e4 + 5;
  37. const int MOD = 20071027;
  38. typedef pair<int, int> pii;
  39. typedef vector<int>::iterator viti;
  40. typedef vector<pii>::iterator vitii;
  41. int purl[55][25], pro[55];
  42. vector<int> ans, num[55], ans2;
  43. int main()
  44. {
  45. //ROP;
  46. int w, i, j, n, cases = 0;
  47. bool first = true;
  48. while (scanf("%d", &w), w)
  49. {
  50. ans.clear();
  51. ans2.clear();
  52. for (i = 1; i <= w; i++) num[i].clear();
  53. for (i = 1; i <= w; i++)
  54. {
  55. scanf("%d", &n);
  56. int tmp, vmax = -1;
  57. for (j = 1; j <= n; j++)
  58. {
  59. scanf("%d", &tmp);
  60. purl[i][j] = purl[i][j - 1] + 10 - tmp;
  61. vmax = max(purl[i][j], vmax);
  62. }
  63. if (vmax >= 0)
  64. {
  65. for (j = 1; j <= n; j++)
  66. if (purl[i][j] == vmax) num[i].PB(j); //num[i],第i个作坊达到最大利润的时候的可以选择的个数
  67. if (vmax == 0) num[i].PB(0); //如果是0的话可以不选
  68. }
  69. pro[i] = vmax; //profit[i]
  70. }
  71. int sum = 0;
  72. for (i = 1; i <= w; i++)
  73. {
  74. if (pro[i] >= 0)
  75. {
  76. sum += pro[i];
  77. if (ans.empty() && ans2.empty())
  78. for (j = 0; j < num[i].size(); j++) ans.PB(num[i][j]);
  79. else if (ans.empty())
  80. {
  81. for (j = 0; j < ans2.size(); j++)
  82. for (int k = 0; k < num[i].size(); k++) ans.PB(ans2[j] + num[i][k]);
  83. ans2.clear();
  84. }
  85. else
  86. {
  87. for (j = 0; j < ans.size(); j++)
  88. for (int k = 0; k < num[i].size(); k++) ans2.PB(ans[j] + num[i][k]);
  89. ans.clear();
  90. }
  91. }
  92. }
  93. if (ans.empty()) sort(ans2.begin(), ans2.end());
  94. else sort(ans.begin(), ans.end());
  95. if (!first) puts("");
  96. first = false;
  97. printf("Workyards %d\n", ++cases);
  98. printf("Maximum profit is %d.\n", sum);
  99. printf("Number of pruls to buy:");
  100. if (ans.empty() && ans2.empty()) printf(" 0");
  101. else if (ans2.empty())
  102. {
  103. int real = unique(ans.begin(), ans.end()) - ans.begin();
  104. for (i = 0; i < min(real, 10); i++) printf(" %d", ans[i]);
  105. }
  106. else
  107. {
  108. int real = unique(ans2.begin(), ans2.end()) - ans2.begin();
  109. for (i = 0; i < min(real, 10); i++) printf(" %d", ans2[i]);
  110. }
  111. puts("");
  112. }
  113. return 0;
  114. }

你可能感兴趣的:(ACM,uva)