AcWing 127. 任务

思考?

样例太弱了,需要自己出样例。分析后就会发现这道题是找最优解的题目,也就是贪心。

先保证完成的任务更多,再保证收入更多。当然实现的时候是同时(考虑)进行的

权值考虑:由于任务的用时对收入的影响更大,那么按任务用时从大到小排序,当用时相同时再考虑任务难度大小。

为了保证遍历机器时更快,机器也同任务一样的方法排序,然后每次取出最长工作时间大于任务时间的机器,检验机器的执行任务难度是否大于任务难度(肯定选当中既小又可以的机器,增加任务的完成度)。

实现效率

为了保证两个遍历都是一遍,我们可以用双指针算法。每次方法同上,只是将取出的机器放入multiset中(而不是优先队列是因为其不支持内部操作),每次用lower_bound查询。

100 pts

#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
const int N = 100010;
PII c[N], task[N];
int n, m;
int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    
    while(cin >> n >> m)
    {
        for(int i = 0; i < n; i ++ ) cin >> c[i].first >> c[i].second;
        for(int i = 0; i < m; i ++ ) cin >> task[i].first >> task[i].second;
        
        sort(c, c + n);
        sort(task, task + m);
        
        multiset<int> w;
        
        ll res = 0, cnt = 0;
        for(int i = m - 1, j = n - 1; i >= 0; i -- )
        {
            //同时保证只遍历一遍机器,也保证每次任务使用的机器充足
            while(j >= 0 && c[j].first >= task[i].first) w.insert(c[j -- ].second);
            multiset<int>::iterator it = w.lower_bound(task[i].second);
            if(it != w.end())
            {
                res += 500 * task[i].first + 2 * task[i].second;
                cnt ++ ;
                w.erase(it);
            }
        }
        cout << cnt << ' ' << res << endl;
    }
    
    return 0;
}
posted @ 2023-01-27 22:29  Sankano  阅读(26)  评论(0编辑  收藏  举报