1 条题解

  • 0
    @ 2025-7-2 15:03:56

    算法:贪心

    对于每一个任务:

    • yy 的差异最多能使利润ww浮动2100=2002 * 100 = 200元。

    • xx11,则会使利润ww浮动500500

    所以,yy对利润的影响较小,xx与其利润ww的关系成对应关系(即xi<xjx_{i} < x_{j},则wi<wjw_{i}<w_{j},仅当xi=xjx_{i} = x_{j},再按照yy考虑即可。

    策略可以变成xx从大到小的顺序考虑每一个任务,如果能匹配机器,则从能匹配的机器中选择机器yy最小的一个。

    匹配机器

    1. 先用xx分别从大到小排序任务与机器。

    2. 对于每一个任务,把时间充足的机器放入集合中。

    3. 若存在,从集合中找出级别最低的机器使用,并且从集合中删除那个机器。

    这种处理顺序可以保证:在处理第下一个任务时,集合中的机器时间都是充足的。且找机器的时间复杂度处于O(M+N)O(M+N)级别。
    STLSTLmultiset\text{multiset}恰好支持从序列中查找大于等于某数的最小值。

    时间复杂度:O(MlogN + N)

    multiset\text{multiset}lowerboundlowerbound时间为O(logN)O(logN)的…

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> PII;
    
    const int N = 100000 + 10;
    int n, m;
    PII a[N],b[N];
    int main(){
        while(cin >> n >> m){
            for(int i = 1; i <= n; i++) cin >> a[i].first >> a[i].second;
            for(int i = 1; i <= m; i++) cin >> b[i].first >> b[i].second;
    
            sort(a + 1,a + 1 + n); sort(b + 1,b + 1 + m);
    
            multiset<int> s; s.clear();
            long long cnt = 0, ans = 0;
            for(int i = m, j = n; i >= 1; i--){
                //将时间足够的机器放到set中 
                while(j >= 1 && b[i].first <= a[j].first)s.insert(a[j--].second);
    
                multiset<int>::iterator it = s.lower_bound(b[i].second);
                if(it != s.end()){
                    cnt ++;
                    ans += 500 * b[i].first + 2 * b[i].second;
                    s.erase(it);
                }
            }
            cout << cnt << " " << ans << endl;
        }
        return 0;
    }
    
    • 1

    信息

    ID
    62
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    40
    已通过
    8
    上传者