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;
}
本文来自博客园,作者:{三季野花},转载请注明原文链接:https://www.cnblogs.com/SanGarden/articles/17069470.html