记录下同类算法题思路

最多可以参加的会议数目

最多可以参加的会议数目
打印最多产品

class Solution {
public:
    int maxEvents(vector<vector<int>>& events) {
        sort(events.begin(), events.end());//按照开始点进行排序
        priority_queue<int,vector<int>, greater<>>pq;//使用优先队列记录最早结束的区间
        int id =  1;//时间点
        int idx = 0; //区间下标
        int n = events.size();
        int ans = 0;//记录答案
        while(idx < n || !pq.empty()){ //这里不是遍历所有时间(只能处理1e6),而是遍历数组,和时间阈值无关
            while(idx < n && events[idx][0] == id){
                pq.push(events[idx++][1]);
            }
            while(!pq.empty() && pq.top() < id){
                pq.pop();
            }
            if(!pq.empty()){
                id++;
                ans++;
                pq.pop();
            }else{
                if(idx<n)
                    id = events[idx][0];
            }
        }
        return ans;
    }
};

最多可以参加的会议数目 II

最多可以参加的会议数目 II
出租车的最大盈利
规划兼职工作

class Solution {
public:
    int maxValue(vector<vector<int>>& events, int k) {
        sort(events.begin(), events.end(),[](const vector<int>& v1, const vector<int>& v2){
            return v1[1] < v2[1]; //按照结束时间排序
        });
        int n = events.size();
        int dp[n+1][k+1];//dp[i][j]表示前i会议最多参加k个会议的最大价值
        memset(dp,0,sizeof dp);
        // vector<vector<int>> dp(n+1, vector<int>(k+1,0));
        for(int i=0;i<n;i++){
            int t = events[i][0]; //二分查找结束时间小于当前开始时间
            int l=0, r=i-1;
            while(l<=r){
                int mid = (l+r) >> 1;
                if(events[mid][1]<t){
                    l = mid+1;
                }else{
                    r = mid-1;
                }
            }
            for(int j=1;j<=k;j++){
                dp[i+1][j] = max(dp[i][j], dp[r+1][j-1] + events[i][2]);
            }
            
        }
        return dp[n][k];
    }
};

会议室 III

会议室 III

class Solution {
public:
    int mostBooked(int n, vector<vector<int>>& meetings) {
        int cnt[n + 1];
        sort(meetings.begin(), meetings.end());
        priority_queue<int, vector<int>, greater<>>pq;
        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>>_using;
        memset(cnt, 0, sizeof cnt);
        int m = meetings.size();
        for (int i = 0; i < n; i++)pq.push(i);
        for(int i=0;i<m;i++){
            long long begin = meetings[i][0], end = meetings[i][1];
            while(!_using.empty() && _using.top().first <= begin){
                pq.push(_using.top().second);
                _using.pop();
            }
            int id;
            if(pq.empty()){
                id = _using.top().second;
                end = end - begin + _using.top().first;
                _using.pop();
            }else{
                id = pq.top();
                pq.pop();
            }
            cnt[id]++;
            _using.push({end, id});

        }
        int mx = 0;
        int ans = 0;
        for (int i = 0; i < n; i++) {
            // cout << cnt[i] << " ";
            if (mx < cnt[i]) {
                ans = i;
                mx = cnt[i];
            }
        }
        return ans;

    }
};

找到处理最多请求的服务器
使用优先队列加线段树

struct tree{
    const static int N = 1e5+5;
    int tr[N<<2];
    int n;
    int MAX=1e9;
    tree(){n = N;}
    tree(int v){n = v;}
    void build(){
        build(1, n, 1);
    }
    void build(int l,int r,int p){
        if(l==r){
            tr[p] = 1;
            return;
        }
        int mid = (l+r)>>1;
        build(l, mid, p<<1);
        build(mid+1, r, p<<1|1);
        tr[p] = tr[p<<1] + tr[p<<1|1];
    }
    void det(int i){
        det(i, 1, n,1);
    }
    void det(int i, int l,int r,int p){
        if(l<=i&&i<=r){
            tr[p]--;
            if(l==r){
                return ;
            }
            int mid=(l+r)>>1;
            det(i,l,mid,p<<1);
            det(i,mid+1,r,p<<1|1);
        }
    }
    void add(int i){
        add(i,1,n,1);
    }
    void add(int i,int l,int r,int p){
        if(l<=i&&i<=r){
            tr[p]++;
            if(l==r){
                return ;
            }
            int mid=(l+r)>>1;
            add(i,l,mid,p<<1);
            add(i,mid+1,r,p<<1|1);
        }
    }
    int ask(int L,int R){
        return ask(L,R, 1,n,1);
    }
    int ask(int L, int R, int l,int r,int p){
        if(!tr[p] || R<l||r<L)return -1;
        if(l==r){
            if(tr[p])return l;
            else return -1;
        }            
        int mid = (l+r)>>1;
        int ans=-1;
        if(tr[p<<1]) ans = ask(L,R,l,mid,p<<1);
        if(ans==-1)ans = ask(L,R,mid+1, r,p<<1|1);
        return ans;
    }
};
class Solution {
public:
    vector<int> busiestServers(int k, vector<int>& arrival, vector<int>& load) {
        tree tr(k);
        tr.build();
        int n = arrival.size();
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>>_using;
        int cnt[k+1];
        memset(cnt, 0, sizeof cnt);
        for(int i=0;i<n;i++){
            int begin = arrival[i], end = arrival[i] + load[i];
            while(!_using.empty() && _using.top().first <= begin){
                tr.add(_using.top().second);
                _using.pop();
            }
            int idx = (i%k)+1;
            int t1 = tr.ask(idx, k);
            if(t1==-1){
                t1 = tr.ask(1, idx-1);
            }
            cout<<t1<<" ";
            if(t1!=-1){
                cnt[t1]++;
                tr.det(t1);
                _using.push({end, t1});
            }
        }
        int mx = *max_element(cnt+1, cnt+k+1);
        vector<int>ans;
        for(int i=1;i<=k;i++){
            if(mx == cnt[i]){
                ans.push_back(i-1);
            }
        }
        return ans;
    }
};

解法2 使用有序列表加优先队列

class Solution {
public:
    vector<int> busiestServers(int k, vector<int>& arrival, vector<int>& load) {
        // tree tr(k);
        // tr.build();
        int n = arrival.size();
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>>_using;
        int cnt[k+1];
        memset(cnt, 0, sizeof cnt);
        set<int> s;
        for(int i=0;i<k;i++){
            s.insert(i);
        }
        for(int i=0;i<n;i++){
            int begin = arrival[i], end = arrival[i] + load[i];
            while(!_using.empty() && _using.top().first <= begin){
                s.insert(_using.top().second);
                _using.pop();
            }
            int idx = (i%k);
            if(!s.empty()){
                auto it = s.lower_bound(idx);
                if(it==s.end())it = s.begin();
                cnt[*it]++;
                _using.push({end, *it});
                s.erase(it);
            }
        }
        int mx = *max_element(cnt, cnt+k);
        vector<int>ans;
        for(int i=0;i<k;i++){
            if(mx == cnt[i]){
                ans.push_back(i);
            }
        }
        return ans;
    }
};

1882. 使用服务器处理任务

// bool operator<(const pair<int,int>&p1,)
class Solution {
public:
    vector<int> assignTasks(vector<int>& servers, vector<int>& tasks) {
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<> > pq;
        priority_queue<pair<int,int>, vector<pair<int,int>>, greater<> > _using;
        int m = servers.size();
        for(int i=0;i<m;i++){
            pq.push({servers[i], i});
        }
        vector<int>ans;
        int begin = 0;//必须维护一个全局变量
        for(int i=0;i<tasks.size();i++){
            while(!_using.empty() && _using.top().first<= i){
                pq.push({servers[_using.top().second], _using.top().second});
                _using.pop();
            }
            // int begin = i;
            int id;
            if(pq.empty()){
                // id = _using.top().second;
                begin = _using.top().first;
                while(!_using.empty()&&_using.top().first == begin){
                    pq.push({servers[_using.top().second], _using.top().second});
                    _using.pop();
                }
                
            }
            begin = max(begin,i);
            id = pq.top().second;
            pq.pop();
            _using.push({begin+tasks[i],id});
            ans.push_back(id);
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_43983809

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值