Dang_Quan_10_Tin

SOLUTION

Aug 23rd, 2020 (edited)
445
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.70 KB | None | 0 0
  1. /*
  2.     Bài này dp thì rất cơ bản, song để AC thì cần thay đổi tư duy
  3.     Bình thường các bạn sẽ toàn làm 3 lặp:
  4.       for(n):
  5.          for(k):
  6.             for(n):
  7.     Tuy nhiên bài này ta sẽ đảo 2 vòng lặp đầu để nhận ra cách tối ưu thuật toán bằng cây IT, chi tiết xem code
  8. */
  9. #define NguyenDangQuan the_author
  10. #define my_heart love_you_to_the_moon_and_back
  11.  
  12. #include <bits/stdc++.h>
  13. using namespace std;
  14. using ll = long long;
  15. using ld = long double;
  16. using ull = unsigned long long;
  17.  
  18. bool typetest;
  19. inline void fastIOfileinput()
  20. {
  21.     ios::sync_with_stdio(0);
  22.     cin.tie(0);
  23.     cout.tie(0);
  24.     typetest = 0;
  25. }
  26.  
  27. const int N = 1e5 + 2;
  28. struct Tho
  29. {
  30.     int l, s, p;
  31.     bool operator<(const Tho &a) const
  32.     {
  33.         return s < a.s;
  34.     }
  35. } a[N];
  36. int n, k;
  37. const ll Inf = 1e14;
  38. ll dp[N][105];
  39. ll st[N * 4];
  40.  
  41. void Read()
  42. {
  43.     cin >> n >> k;
  44.     ++n;
  45.     for (int i = 1; i <= k; ++i)
  46.         cin >> a[i].l >> a[i].p >> a[i].s,
  47.             ++a[i].s;
  48.     sort(a + 1, a + k + 1);
  49. }
  50.  
  51.  //// f(i, j) là số tiền nhiều nhất thu được nếu ở vị trí thứ i chọn j làm thằng sơn
  52. //// dp(i, j) : là max tất cả các f(i, t) mà t <= j
  53. //// => dp(i, j) = max(dp(t, j - 1) + (i - t) * a[j].p) với mọi t : 0 -> i
  54.  
  55. void Upd(int id, int l, int r, int &pos, ll v)
  56. {
  57.     if (l > pos || r < pos)
  58.         return;
  59.     if (l == r && r == pos)
  60.     {
  61.         st[id] = max(st[id], v);
  62.         return;
  63.     }
  64.     Upd(id << 1, l, (l + r) / 2, pos, v);
  65.     Upd(id << 1 | 1, (l + r) / 2 + 1, r, pos, v);
  66.     st[id] = max(st[id << 1], st[id << 1 | 1]);
  67. }
  68.  
  69. ll Get(int id, int l, int r, int a, int b)
  70. {
  71.     if (l > b || r < a)
  72.         return -Inf;
  73.     if (l >= a && r <= b)
  74.         return st[id];
  75.     return max(Get(id << 1, l, (l + r) / 2, a, b), Get(id << 1 | 1, (l + r) / 2 + 1, r, a, b));
  76. }
  77.  
  78. void Solve()
  79. {
  80.     fill_n(&dp[0][0], N * 105, -Inf);
  81.     dp[1][0] = 0;
  82.     for (int j = 1; j <= k; ++j)
  83.     {
  84.         fill_n(st, N * 4, -Inf);
  85. /// Đây là vòng lặp đầu bị đảo vào trong
  86.         for (int i = 1; i <= n; ++i)
  87.             dp[i][j] = dp[i][j - 1],
  88.             Upd(1, 1, n, i, dp[i][j - 1] - (ll)i * a[j].p);
  89. /// Lúc này vòng lặp thứ 3 không còn bị lồng vào trong vòng lặp đầu nữa
  90.         for (int i = a[j].s; i < a[j].s + a[j].l; ++i)
  91.         {
  92.             dp[i][j] = max(dp[i][j], Get(1, 1, n, max(i - a[j].l, 1), a[j].s - 1) + (ll)i * a[j].p);
  93.         }
  94.     }
  95.     /*for (int i = 2; i <= n; ++i)
  96.         for (int j = 1; j <= k; ++j)
  97.             cout << dp[i][j] << (j == k ? "\n" : " ");*/
  98.     ll ans = -Inf;
  99.     for (int i = n; i > 1; --i)
  100.         ans = max(ans, dp[i][k]);
  101.     cout << ans;
  102. }
  103.  
  104. int32_t main()
  105. {
  106.     fastIOfileinput();
  107.     if (typetest)
  108.     {
  109.         int t;
  110.         cin >> t;
  111.         while (t--)
  112.         {
  113.             Read();
  114.             Solve();
  115.         }
  116.     }
  117.     else
  118.     {
  119.         Read();
  120.         Solve();
  121.     }
  122. }
Advertisement
Add Comment
Please, Sign In to add comment