返回列表 發帖

202406潛力2-會議室租用MeetingRoom_找不到judge


大明經營一間專門租用共享空間的公司,由於需求太過熱門,目前只剩下一間會議室可供出租。已知還有 N 位客戶在等候租用,第 i位客戶需要租用時間ai到 bi(包含 ai和 bi)並會支付 ci元。公司希望在使用會議室的時間不衝突的情況之下選擇一些客戶使得收入最大化。 例如:有N = 3位客戶,需要會議室的時段與支付費用如下表所示。最大化收入的策略為選擇第1和3位客戶,收入為6+3=9元。

輸入格式
第一列有一個正整數 N ( N ≤ 2×105),表示有 N 位客戶。接下來 N 列,每列有三個正整數 ai, bi, ci ( ai ≤ bi ≤ 106, ci ≤ 104),兩個正整數之間以一個空白為間
隔,表示第 i 位客戶要從時段 ai到 bi (包含 ai和 bi) 支付 ci元租用會議室。
輸出格式
請輸出一個非負整數,表示最大收入。

評分說明
此題目測資分成四組,每組測資有多筆測試資料,需答對該組所有測試資
料才能獲得該組分數,各組詳細限制如下。
第一組 (20 分):N ≤ 10。
第二組 (20 分):所有的 ci = 1。
第三組 (30 分):N ≤ 103。
第四組 (30 分):無特別限制。
附件: 您需要登錄才可以下載或查看附件。沒有帳號?註冊
May

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<vector>
  4. #include<algorithm>
  5. using namespace std;
  6. const int N = 200000 + 5;

  7. struct Case {
  8.         int l, r, w;
  9. };

  10. int solve(int n, const int l[N], const int r[N], const int w[N])
  11. {
  12.         static Case v[N];
  13.         static int dp[N];
  14.        
  15.         for (int i = 0; i < n; ++i)
  16.         {
  17.                 v[i] = (Case){l[i], r[i], w[i]};
  18.         }
  19.         sort(v, v + n, [](const auto& lhs, const auto& rhs) {
  20.                 return lhs.r < rhs.r;
  21.         });
  22.         dp[0] = v[0].w;
  23.         for (int i = 1; i < n; ++i)
  24.         {
  25.                 int cur;
  26.                 int pos = lower_bound(v, v + i, (Case){0, v[i].l, 0}, [](const auto& lhs, const auto& rhs) {
  27.                         return lhs.r < rhs.r;
  28.                 }) - v - 1;
  29.                
  30.                 if (pos < 0)
  31.                 {
  32.                         cur = v[i].w;
  33.                 }
  34.                 else
  35.                 {
  36.                         cur = dp[pos] + v[i].w;
  37.                 }
  38.                 dp[i] = max(dp[i - 1], cur);
  39.         }
  40.         return dp[n - 1];
  41. }

  42. int main()
  43. {
  44.         int n;
  45.         static int l[N], r[N], w[N];
  46.         scanf("%d", &n);
  47.         for (int i = 0; i < n; ++i)
  48.         {
  49.                 scanf("%d%d%d", &l[i], &r[i], &w[i]);
  50.         }
  51.         printf("%d\n", solve(n, l, r, w));
  52.         return 0;
  53. }
複製代碼
May

TOP

  1. //#include <iostream>
  2. //#include <vector>
  3. //#include <algorithm>
  4. #include <bits/stdc++.h>
  5. using namespace std;

  6. // 定義結構存儲客戶資料
  7. struct Customer {
  8.     int start, end, profit;
  9. };

  10. // 比較函數:按結束時間排序
  11. bool compareByEnd(const Customer &a, const Customer &b) {
  12.     return a.end < b.end;
  13. }

  14. // 二分搜尋:找到不重疊的最後一個客戶
  15. int findLastNonConflict(const vector<Customer> &customers, int index) {
  16.     int low = 0, high = index - 1;
  17.     while (low <= high) {
  18.         int mid = (low + high) / 2;
  19.         if (customers[mid].end < customers[index].start) {
  20.             if (customers[mid + 1].end < customers[index].start) {
  21.                 low = mid + 1;
  22.             } else {
  23.                 return mid;
  24.             }
  25.         } else {
  26.             high = mid - 1;
  27.         }
  28.     }
  29.     return -1;
  30. }

  31. int main() {
  32.     int N;
  33.     cin >> N;

  34.     vector<Customer> customers(N);
  35.     for (int i = 0; i < N; ++i) {
  36.         cin >> customers[i].start >> customers[i].end >> customers[i].profit;
  37.     }

  38.     // 按結束時間排序
  39.     sort(customers.begin(), customers.end(), compareByEnd);

  40.     // 動態規劃陣列
  41.     vector<long long> dp(N);
  42.     dp[0] = customers[0].profit;

  43.     for (int i = 1; i < N; ++i) {
  44.         // 包含當前客戶的收益
  45.         long long includeProfit = customers[i].profit;
  46.         int last = findLastNonConflict(customers, i);
  47.         if (last != -1) {
  48.             includeProfit += dp[last];
  49.         }

  50.         // 不包含當前客戶的收益
  51.         dp[i] = max(dp[i - 1], includeProfit);
  52.     }

  53.     // 輸出最大收益
  54.     cout << dp[N - 1] << endl;

  55.     return 0;
  56. }
  57. /*
  58. 輸入:
  59. 3
  60. 1 4 6
  61. 2 7 8
  62. 5 6 3
  63. 輸出:
  64. 9
  65. --------
  66. 6
  67. 2 3 3
  68. 3 4 2
  69. 4 5 2
  70. 6 7 3
  71. 2 6 8
  72. 1 4 6

  73. */
複製代碼
--------------------------------------------------------
先備知識:1.struct 2.vector 3.vector排序 4.二分搜  5動態規劃
程式解釋
輸入處理:
讀取客戶數量 N 和每位客戶的租用時間及收益。
排序:
根據每位客戶的結束時間 bi 對客戶進行排序。
二分搜尋:
使用 findLastNonConflict 找到對應客戶中不與當前客戶重疊的最後一個客戶。
動態規劃:
計算包含或不包含當前客戶的收益,並取兩者的最大值。
輸出結果:
最終結果即為 dp[N-1],即最大收益。
時間複雜度
排序:
May

TOP

返回列表