fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. using ll = long long;
  4. const ll NEG = (ll)-4e18;
  5.  
  6. int main(){
  7. ios::sync_with_stdio(false);
  8. cin.tie(nullptr);
  9. int n, T;
  10. if (!(cin >> n >> T)) return 0;
  11. vector<int> t(n), q(n);
  12. for (int i = 0; i < n; ++i) cin >> t[i] >> q[i];
  13.  
  14. // group tasks by cap = T - t[i]
  15. vector<vector<int>> byCap(T+1);
  16. for (int i = 0; i < n; ++i) {
  17. int cap = T - t[i];
  18. if (cap >= 0 && cap <= T) byCap[cap].push_back(q[i]);
  19. }
  20. // sort each level decreasing and build prefix sums
  21. vector<vector<ll>> pref(T+1);
  22. for (int h = 0; h <= T; ++h) {
  23. auto &v = byCap[h];
  24. sort(v.begin(), v.end(), greater<int>());
  25. pref[h].assign(v.size()+1, 0);
  26. for (size_t k = 1; k <= v.size(); ++k) pref[h][k] = pref[h][k-1] + v[k-1];
  27. }
  28.  
  29. int MAXC = n; // số nút ở 1 mức không vượt quá n
  30. // D[h][c] : giá trị tối đa đã thu được từ mức > h khi hiện có c nút ở mức h
  31. vector<vector<ll>> D(T+1, vector<ll>(MAXC+1, NEG));
  32.  
  33. // Khởi: ở mức sâu nhất (h = T) "không có cấp sâu hơn", nên đóng góp dưới cùng = 0
  34. // Ta cho D[T][c] = 0 cho mọi c (tức chưa thu gì từ dưới)
  35. for (int c = 0; c <= MAXC; ++c) D[T][c] = 0;
  36.  
  37. // sweep từ h = T xuống h = 0
  38. ll answer = 0; // có thể là 0 (không chọn task nào)
  39. for (int h = T; h >= 0; --h) {
  40. // nếu h == 0 thì khi cập nhật lên h-1 thực tế là kết thúc -> ta thu kết quả vào answer
  41. for (int c = 0; c <= MAXC; ++c) {
  42. if (D[h][c] == NEG) continue;
  43. int maxk = min((int)byCap[h].size(), c);
  44. for (int k = 0; k <= maxk; ++k) {
  45. ll val = D[h][c] + pref[h][k];
  46. int newC = (c + k + 1) / 2; // ceil((c+k)/2)
  47. if (h == 0) {
  48. // ở mức 0: muốn có đúng 1 nút (root). newC phải là 1
  49. if (newC == 1) answer = max(answer, val);
  50. } else {
  51. // cập nhật cho mức trên (h-1)
  52. D[h-1][newC] = max(D[h-1][newC], val);
  53. }
  54. }
  55. }
  56. }
  57.  
  58. cout << answer << '\n';
  59. return 0;
  60. }
  61.  
Success #stdin #stdout 0.01s 5320KB
stdin
5 5
1 1
1 1
2 2
3 3
4 4
stdout
11