HDU 4864 Task (贪心)

Task

题目链接:

http://acm.hust.edu.cn/vjudge/contest/121336#problem/B

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 completes this task, they will get (500xi+2yi) dollars.
The company has n machines. Each machine has a maximum working time and a level. If the time for the task is more than the maximum working time of the machine, the machine can not complete this task. Each machine can only complete a task one day. Each task can only be completed by one machine.
The company hopes to maximize the number of the tasks which they can complete today. If there are multiple solutions, they hopes to make the money maximum.

Input

The input contains several test cases.
The first line contains two integers N and M. N is the number of the machines.M is the number of tasks(1 < =N <= 100000,1<=M<=100000).
The following N lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the maximum time the machine can work.yi is the level of the machine.
The following M lines each contains two integers xi(0<xi<1440),yi(0=<yi<=100).xi is the time we need to complete the task.yi is the level of the task.

Output

For each test case, output two integers, the maximum number of the tasks which the company can complete today and the money they will get.

Sample Input

1 2
100 3
100 2
100 1

Sample Output

1 50004


##题意: 有n台机器和m个任务,每台机器有对应的工作时间和难度上限,每个任务有时间需求和难度. 每个任务的报酬由时间和难度决定(500*x+2*y). 求最多完成多少任务,任务数相同时报酬尽量多.
##题解: 一开始看题目以为是每个任务有时间\难度\金钱三个因素,不方便进行贪心操作. 仔细观察题目数据范围和所给的公式后发现:时间x增加1报酬会增加500,而难度最多增加100会提升报酬200; 所以时间才是决定报酬的要素,按照时间降序排列(时间相等时难度降序)后,任务的报酬也就有序了.
现在的问题是对于每个任务,如何选取完成这个任务的机器: 由于我们对机器和任务都排序过,那么时间上能满足当前任务的机器一定也能够满足接下来任务.
而对于若干个时间上满足当前任务的机器,应该选择难度上限尽量小(但满足当前任务)的机器; 而留下难度上限大的机器以待完成后面的需求.
算法流程: 先对机器和任务都按照上述规则排序: 依次扫描每个任务,先找到时间上满足任务要求的全部机器,并将它们的难度上限在数组中标记出来(因为难度的范围只有100,记录每个难度有多少机器能应对即可). 最后找出最小能满足任务难度要求的机器即可. WA点:难度是从0开始的; 报酬总数要用longlong

##代码: ``` cpp #include #include #include #include #include #include #include #include #include #define LL long long #define eps 1e-8 #define maxn 101000 #define mod 100000007 #define inf 0x3f3f3f3f #define IN freopen("in.txt","r",stdin); using namespace std;

int n, m;
typedef pair<int,int> pii;
pii machine[maxn];
pii task[maxn];
int lev_cnt[110];

int main(int argc, char const *argv[])
{
//IN;

while(scanf("%d %d", &n,&m) != EOF)
{
    memset(lev_cnt, 0, sizeof(lev_cnt));
    for(int i=1; i<=n; i++) {
        int x,y; scanf("%d %d", &x,&y);
        machine[i] = make_pair(x,y);
    }
    for(int i=1; i<=m; i++) {
        int x,y; scanf("%d %d", &x,&y);
        task[i] = make_pair(x,y);
    }
    sort(machine+1, machine+1+n, greater<pii>());
    sort(task+1, task+1+m, greater<pii>());

    int finish = 0;
    LL money = 0;
    for(int i=1,j=1; i<=m; i++) {
        int t = task[i].first;
        int lev = task[i].second;
        for(; j<=n; j++) {
            if(machine[j].first >= t)
                lev_cnt[machine[j].second]++;
            else break;
        }

        for(int k=0; k<=100; k++) {
            if(!lev_cnt[k]) continue;
            if(k >= lev) {
                lev_cnt[k]--;
                finish++;
                money += 500LL*(LL)t + 2LL*(LL)lev;
                break;
            }
        }
    }

    printf("%d %I64d\n", finish, money);
}

return 0;

}

posted @ 2016-07-27 17:20  Sunshine_tcf  阅读(321)  评论(0编辑  收藏  举报