HDU 4864 Task(贪心值得学习)

题目链接:戳我

题目大意:

有 M 个任务,每个任务有两个属性 x, y, x 代表完成这个任务需要多久时间, y代表这个任务的难度系数

有 N 个机器,每个机器同样也有两个属性 x ,y,x代表这个机器每天最长工作时间, y代表这个机器最高能完成的难度系数,且一天只能工作一次,即只能完成一个任务

如果完成了一个任务, 会获得 500 * x + 2 * y 元,x,y为对应任务的x和y

问 一天内 最多可以完成 多少任务, 完成这么多任务 所获得的最大利润

样例解释:

1 2 ----- 1 为 机器数 N, 2为任务数 M 接下来 先是 N行,每行两个代表机器属性,同理 下面M行

100 3 

100 2

100 1

(100 3) 这个机器 完成 (100 2) 这个 1 任务 所获 利润 500*100+2* = 50004

解题思路:

如果选择 双重 for 循环去遍历,肯定是可以的,但是会超时,所以要优化,抛弃 for 循环的冗余部分,对于每个 任务,不用遍历所有的机器 去找到合适的。

取 机器 的游标 j,j表示所有机器中能完成该任务的下限机器,每次从当前 j 开始寻找最合适的 j。

首先 把 任务 和 机器 都按照 x 从大到小排序,x相同y从大到小排序, 排序之后从头到尾遍历每一个任务对于  每一个 任务, 选择 所有 合适 的机器 中 y 最小的那个,

巧妙的代码:

 

//Author LJH
//www.cnblogs.com/tenlee
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#define clc(a, b) memset(a, b, sizeof(a))
using namespace std;

const int inf = 0x3f;
const int INF = 0x3f3f3f3f;
const int maxn = 1e6+5;

struct Task
{
    int x, y;
}task[maxn], mac[maxn];
int n, m;
int ha[maxn];

bool cmp(Task A, Task B)
{
    if(A.x == B.x) return A.y > B.y;
    return A.x > B.x;
}
int main()
{
    while(~scanf("%d %d", &n, &m))
    {
        for(int i = 0; i < n; i++)
        {
            scanf("%d %d", &mac[i].x, &mac[i].y);
        }
        for(int i = 0; i < m; i++)
        {
            scanf("%d %d", &task[i].x, &task[i].y);
        }
        sort(mac, mac+n, cmp);
        sort(task, task+m, cmp);
        memset(ha, 0, sizeof(ha));
        int j = 0, k = 0, num = 0;
        long long ans = 0;
        for(int i = 0; i < m; i++) 
        {
            while(j < n && (mac[j].x >= task[i].x)) // 找到 下限 的 机器 j 
            {
                ha[mac[j].y]++; //把所有 x 合适的 机器的 y 记下来
                j++;
            }
            for(k = task[i].y; k <= 100; k++)
            {
                if(ha[k]) //从 x 合适 的机器 中 挑选 y 也合适, 同时 y 最小
                {
                    ans += (500 * task[i].x + 2 * task[i].y);
                    ha[k]--; //该机器已用,减去
                    num++;
                    break;
                }
            }
        }
        printf("%d %lld\n", num, ans);
    }
    return 0;
}

 

  

 

posted @ 2015-07-17 19:12  豪气干云  阅读(310)  评论(0编辑  收藏  举报