classsolution { public: // 注意,比较函数不能直接写在类内部,需加上static静态函数,否则类外调用sort无法访问cmp函数 // 或者将cmp函数写在类的外部,以及用lambda表达式[&](int& a,int& b){return a < b;} staticboolcmp(vector<int>& a, vector<int>& b){ // 比较两个任务信息数组,按照结束时间进行升序排序 return a[2] < b[2]; } // 辅助函数 将任务信息数组转化为string类型便于哈希表存储 string help(vector<int> arr){ string s; for (auto a : arr) { s += to_string(a); } return s; } // 主函数 vector<int> schedule(vector<vector<int>> arr){ int n = arr.size(); unordered_map<string, int> mp; // 哈希表存储任务信息列表对应的原始索引值 for (int i = 0; i < n; i++) { mp.insert(make_pair(help(arr[i]), i)); } // 便于计算,这里插入一个0进程的调度信息,这样排序后的第i个任务就是arr[i] arr.push_back({0, 0, 0}); // 按照结束时间进行升序排序 sort(arr.begin(), arr.end(), cmp); // 辅助数组p,记录当前区间之前,最近的一个不重叠区间的位置 vector<int> p(n + 1, 0); for (int i = 1; i <= n; i++) { for (int j = i-1; j > 0; j--) { if (arr[j][2] <= arr[i][1]) { p[i] = j; break; } } }
vector<int> res; // 记录结果 vector<int> dp(n + 1, 0);// dp数组,记录当前i个区间的最优解,dp[i]为当前的最大权重和 dp[0] = 0; // dp递推关系 for (int i = 1; i <= n; i++) { if (dp[p[i]] + arr[i][0] >= dp[i-1]) { // 执行第i个区间 dp[i] = dp[p[i]] + arr[i][0]; } else { // 不执行第i个区间 dp[i] = dp[i - 1]; } } int maxVal = dp[n]; // 区间n的最大权重和 int index = 0; // 倒序遍历dp数组 for (int i = n; i > 0; i--) { // 找到执行的区间位置 if (dp[i] == maxVal && dp[i - 1] != maxVal) { index = i; res.push_back(mp[help(arr[index])]); maxVal = dp[p[index]]; //maxVal -= arr[index][0]; } } sort(res.begin(), res.end()); // 注意结果要求升序排序 return res; } };
intmain(){ int n, num; cin >> n >> num; vector<vector<int>> arr(n); int len = n; int wi = 0, si = 0, fi = 0; while (n--) { cin >> wi >> si >> fi; arr[len - n - 1].push_back(wi); arr[len - n - 1].push_back(si); arr[len - n - 1].push_back(fi); } /* arr1 = {{2,0,4}, {4,1,6}, {4,5,7}, {7,2,9}, {2,8,10}, {1,8,11}}; 输出:0 2 4 arr2 = {{3,0,6},{1,1,4},{4,3,5},{17,3,8},{9,4,7},{10,5,9},{8,6,10},{1,8,11}}; 输出:3 7 */ vector<int> res; solution test; res = test.schedule(arr); for (auto& v : res) { cout << v << " "; } return0; }