hdu4864不是一般的贪心

题目表达的非常清楚,也不绕弯刚开始以为最大权匹配,仔细一想不对,这题的数据双循环建图都会爆,只能先贪心试一下,但一想贪心也要双循环啊,怎么搞?

想了好久没头绪,后来经学长提醒,可以把没用到的先记录下来嘛,以后就不用从头去找了,就像cache一样。我想了想就忽然开窍了,对啊,任务的价值只是一到一百而已,把先前遍历到的没用到的机器先记录下来,以后碰到合适的就不用再从头搜到尾了啊!这样外层100000里层100应该是能过的!

那么就用一个数组来标记机器的价值,cache[i]   表示价值i的机器有多少个,用任务去找机器,也就是说外层循环是任务,每次先通过循环根据机器时间大于等于任务时间把符合的机器加到cache数组里,然后就要先明确一个贪心的原则,就是不浪费,也就是说第j个任务找机器的时候一定是找和它最近的机器是最符合的,你想啊,某台机器价值为8,某个任务价值为1,他们两匹配上了是不是很浪费?最不浪费的做法就是匹配相等价值的,但这太理想了,所以必须匹配价值最接近的!既然如此的话,就必须想排个序了,由大到小排,最后一个循环从任务的价值开始往上找合适的机器,找到了就把cache数组更新一下。这样这道题就ko了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

struct tam
{
    __int64 time,money;
}machine[100005],task[100005];
int cache[1005];
bool cmp(tam X,tam Y)
{
    if(X.time==Y.time) return X.money>Y.money;
    else return X.time>Y.time;
}
int main()
{
    int n,m;
            int c=0;
        __int64 sum=0;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        c=sum=0;
        memset(cache,0,sizeof(cache));
        for(int i=0;i<n;i++)
            scanf("%I64d%I64d",&machine[i].time,&machine[i].money);
        sort(machine,machine+n,cmp);
        for(int j=0;j<m;j++)
            scanf("%I64d%I64d",&task[j].time,&task[j].money);
        sort(task,task+m,cmp);
        int a,b;
        for(a=0,b=0; a<m;a++)
        {
            while(b<n&&machine[b].time>=task[a].time)
            {
                cache[machine[b].money]++;
                b++;
            }
            for(int k=task[a].money;k<=100;k++)
            {
                if(cache[k])
                {
                    cache[k]--;
                    c++;
                    sum += (500*task[a].time+2*task[a].money);
                    break;
                }
            }
        }
        printf("%d %I64d\n",c,sum);
    }
}
时间: 2024-10-12 12:42:52

hdu4864不是一般的贪心的相关文章

hdu 1050(贪心算法)

Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 19278    Accepted Submission(s): 6582 Problem Description The famous ACM (Advanced Computer Maker) Company has rented a floor of a

codevs 1472 体检

题目描述 Description 郑厂长不是正厂长 也不是副厂长 他根本就不是厂长 只是公司的一个码农 郑厂长所在的公司每一年都要组织员工体检,比如量身高体重.测血压之类的,今年也不例外. 这次总共有N位员工接受体检,并且每个员工都需要做K个项目的检查才算完成整个体检的流程.现在来了M个医生为员工做身体检查,并且每一位医生都带齐了检查这K个项目的器材来(也就是说每个医生都能进行这K个项目中的任意一项检查). 体检的详细流程是这样的: 公司事先制定好了M份体检单,每个医生手上都各自拿到一份体检单,

bzoj 1200: [HNOI2005]木梳 DP

1200: [HNOI2005]木梳 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 266  Solved: 125[Submit][Status] Description Input 第一行为整数L,其中4<=L<=100000,且有50%的数据满足L<=104,表示木板下侧直线段的长.第二行为L个正整数A1,A2,…,AL,其中1 Output 仅包含一个整数D,表示为使梳子面积最大,需要从木板上挖掉的格子数. Sample Inpu

算法分级

简单的模拟,简单的模板,极为简单的数据结构,极为简单的技巧. 简单的贪心/动态规划,简单的技巧,计算几何题,倍增,01分数规划,一般的背包,一般的期望题,一般的动态规划优化,简单的数论/矩阵,矩阵树定理,一般的莫比乌斯反演,量产数据结构,简单的分块/莫队,一般的字符串,简单的网络流,简单的图论. 带权二分,二进制分组,一般的贪心/动态规划,决策单调性优化,虚树,斯坦纳树,原根,二次剩余,欧拉函数,一般的数论/矩阵,简单的计数,生成函数,博弈论,洲阁筛/Min_25筛,困难的分治,KD树,一般的分

DP(动态规划)学习心得

动态规划学习心得 说实话吧,动态规划(DP)确实是一个比较难的知识点,对于初学者来说,是一个难过的坎(笔者的脸呢?开玩笑.).动态规划就是我从初学开始遇到的最神奇的解法,它不同于暴力搜索,也不同于一般的贪心,能够以出乎人意料的时间复杂度(近似于O(n^2))解决一些难题,算法远远优于一般的深搜(O(2^n)).不过,动态规划的思维性比较强,必须会设好状态,正确写出状态转移方程,并且能够准确判断有无最优子结构. 其实有点像贪心,但是它有局部最优解推导向整体最优解的过程,形象一点说,动态规划的“眼光

贪心——HDU4864

对应HDU题目:点击打开链接 Task Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3427    Accepted Submission(s): 887 Problem Description Today the company has m tasks to complete. The ith task need xi minut

[HDU4864]Task (贪心)

此图和上一篇博客的图一起看有奇效 题意 https://vjudge.net/problem/HDU-4864 思路 贪心 代码 by lyd 我实在是敲不来 #include <iostream> #include <cstdio> #include <cstring> #include <ctime> #include <algorithm> #include <cmath> #include <queue> #inc

HDU4864:Task(贪心)

Problem Description Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task's level yi cannot complete this task. If the company comp

[转]五大常用算法:分治、动态规划、贪心、回溯和分支界定

Referred from http://blog.csdn.net/yapian8/article/details/28240973 分治算法 一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求