• 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
    ", num, ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    ADO.NET 数据连接查询
    弹出消息对话框类
    C# 火星文转化 算法 dictionary 的使用案例
    微软官方的SqlHelper
    jsHelper
    【VC++积累】之六、MFC简要剖析
    C# 统计文章中字符的种类和个数 哈希表和字典的使用
    C# NetHelper
    C# XML操作类 XmlHelper
    【VS++积累】之七、黑客编程之匿名管道
  • 原文地址:https://www.cnblogs.com/tenlee/p/4655450.html
Copyright © 2020-2023  润新知