HDU4864:Task(贪心)

题意挺简单,我看英文都能看懂(骄傲ヽ( ̄▽ ̄)ノ)
然后就是贪心策略了…思路(;´ρ`)…ヽ(´~`;)
想了好多思路啊,然后没有一个对的来着…不知不觉就是一下午。然后看了看别人的…有道理、。、

知道了思路,我就准备代码实现,用优先队列去试了试水,没做出来,无奈最后看了看别人的代码,明白了咋回事

至于思路就是时间的影响大,所以机器和任务优先时间降序,当任务所耗费的时间所需相等时在按难度降序。

我一开始的时候机器找任务,这样就影响了最大匹配…

而任务找机器就可以尽最大可能寻找合适的机器匹配,这样就能保证了最大匹配数。
其次,优先的是时间,其次是难度。所以在保证机器时间合适(大于等于任务时间)的情况下,找难度较小且满足任务的机器。

百度的ac的代码千篇一律,因为我是看的别人的。所以代码也很相似
在这主要是写一下思路

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 100000+66
int n,m;
struct node{
    int x;
    int y;
}task[maxn],machine[maxn];
bool cmp(const node a, const node b){
    if(a.x == b.x) return a.y > b.y;
    return a.x > b.x;
}
int level[100+6]; //难度为i的机器数
int main(){

    while(cin >> n >> m){
        for(int i = 0; i < n; ++i) cin >> machine[i].x >> machine[i].y;
        for(int i = 0; i < m; ++i) cin >> task[i].x >> task[i].y;
        sort(machine,machine+n,cmp);
        sort(task,task+m,cmp);
        memset(level,0,sizeof(level));
        int j = 0, cnt = 0; long long sum = 0;
        for(int i = 0; i < m; ++i){
            while(j < n && machine[j].x >= task[i].x ){
                level[machine[j].y]++; //该机器时间满足,然后该难度的机器数+1
                j++;
            }//循环结束,满足该任务所有符合时间条件的机器都找到了
            for(int k = task[i].y; k <= 100; ++k){
            //从该任务难度开始遍历,从该难度到100选择最小的不为0的机器数,数量-1
                if(level[k]){
                    level[k]--;
                    sum+=500*task[i].x+2*task[i].y;
                    cnt++;
                    break;
                }
            }
            //开始下一种任务,该任务的时间没有上一个时间大,所以之前没用过难度的机器还能用
        }
       cout << cnt << ' ' << sum << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44031744/article/details/86765946