fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. int main() {
  5. ios::sync_with_stdio(false);
  6. cin.tie(nullptr);
  7.  
  8. int n, m;
  9. if (!(cin >> n >> m)) return 0;
  10. vector<int> l(n);
  11. for (int &x : l) cin >> x;
  12. vector<int> s(n);
  13. for (int &x : s) cin >> x;
  14.  
  15. vector<long long> A(m + 1);
  16. for (int i = 1; i <= m; ++i) cin >> A[i];
  17.  
  18. int L = n + m; // maximal possible grade
  19. vector<long long> B(L + 2, 0); // B[1] is unused, B[L+1] = 0
  20. for (int i = 1; i <= L; ++i) cin >> B[i];
  21. vector<long long> D(L + 1);
  22. for (int i = 1; i <= L; ++i) cin >> D[i];
  23.  
  24. /* profit of each crystal = A[grade] - cost */
  25. vector<vector<long long>> profit(L + 1);
  26. for (int i = 0; i < n; ++i) {
  27. int g = l[i]; // 1 … m
  28. long long p = A[g] - (long long)s[i];
  29. profit[g].push_back(p);
  30. }
  31.  
  32. /* prefix sums of the best k profits for every grade */
  33. vector<vector<long long>> pref(L + 1);
  34. for (int v = 1; v <= L; ++v) {
  35. auto &vec = profit[v];
  36. sort(vec.begin(), vec.end(), greater<long long>());
  37. pref[v].assign(vec.size() + 1, 0);
  38. for (size_t k = 1; k <= vec.size(); ++k)
  39. pref[v][k] = pref[v][k - 1] + vec[k - 1];
  40. }
  41.  
  42. const long long NEG = -(1LL << 60);
  43. vector<long long> dp(n + 1, NEG), nxt(n + 1, NEG);
  44. dp[0] = 0; // nothing chosen yet
  45.  
  46. for (int v = 1; v <= L; ++v) {
  47. int cnt = (int)pref[v].size() - 1; // number of crystals of this grade
  48. long long Bnext = (v < L) ? B[v + 1] : 0LL;
  49. fill(nxt.begin(), nxt.end(), NEG);
  50. for (int c = 0; c <= n; ++c) if (dp[c] != NEG) {
  51. for (int k = 0; k <= cnt; ++k) {
  52. int total = c + k;
  53. int nc = total >> 1; // new carry
  54. long long gain = pref[v][k];
  55. if (total & 1) gain += D[v];
  56. gain += (long long)nc * Bnext;
  57. long long cand = dp[c] + gain;
  58. if (cand > nxt[nc]) nxt[nc] = cand;
  59. }
  60. }
  61. dp.swap(nxt);
  62. }
  63.  
  64. long long answer = dp[0];
  65. if (answer < 0) answer = 0; // empty set is always possible
  66. cout << answer << '\n';
  67. return 0;
  68. }
Success #stdin #stdout 0.01s 5320KB
stdin
3 2
1 1 2
2 1 3
4 5
0 2 1 1 1
0 3 0 0 0
stdout
10