力扣1235 2024.5.4

原题网址:https://leetcode.cn/problems/maximum-profit-in-job-scheduling/submissions/529098063/

个人难度评价:1600

分析:一眼DP,考虑DP顺序,DP递推式与边界
十分类似背包,记i为第i段时间,显然有dp[i]=max(dp[i-1], dp[b[i]]+p[i])
由此得出递推顺序为按结束时间为第一关键字升序递推。边界自然可知

源码:此处直接使用map存储方便处理与查找。离散化也可。

//Code with C++
// 1235
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;

class Solution {
public:
    int jobScheduling(vector<int>& startTime, vector<int>& endTime, vector<int>& profit){
        int n = startTime.size();
        vector<pair<pair<int, int>, long long>> m;
        m.push_back({{0, 0}, 0});
        for (int i=0; i<n; i++){
            m.push_back({{endTime[i], startTime[i]}, profit[i]});
        }
        sort(m.begin(), m.end());
        map<int, long long> dp;
        int s, e;
        long long v;
        long long ans = 0;
        for (int i=1; i<=n; i++){
            e = m[i].first.first;
            s = m[i].first.second;
            v = m[i].second;
            auto p = dp.lower_bound(s);
            if (p->first == s)
                v += p->second;
            else{
                if (p != dp.begin()){
                    v += (--p)->second;
                }
            }
            dp[e] = max(dp[e], v);
            dp[e] = max(dp[e], (--dp.find(e))->second);
            ans = max(dp[e], ans);
        }
        return ans;
    }
};

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    Solution s;
    vector<int> a = {1,2,3,4,6};
    vector<int> b = {3,5,10,6,9};
    vector<int> c = {20,20,100,70,60};
    cout << s.jobScheduling(a, b, c);
    return 0;
}```
posted @ 2024-05-04 17:34  训练师马文  阅读(13)  评论(0)    收藏  举报