ACM题解——贪心——调度问题

ACM题解——贪心——调度问题

题目描述

Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.

 

Input

The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.

 

Output

For each test case, you should output the smallest total reduced score, one line per test case.

 

Sample Input

3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4

Sample Output

0
3
5

题意

有n个任务,给定n个任务的截止时间和没有完成任务的惩罚,任务必须在截止时间当天及之前完成,否则就有惩罚,求出惩罚的最小值。

 

题解

首先构建一个结构体,存放每个任务的截止时间和相应的惩罚,再根据最大的限制时间开一个时间槽数组,将任务按照惩罚从大到小排序(思想就是在限制范围内有限把惩罚大的完成),开一个for循环,遍历每个任务,查看每个任务对应的限制时间的那一天是否为空,若空则放入该任务即标记为满,若非空则从该时间槽开始往前找空的时间槽存放,若没有空的时间槽,则让惩罚记录+=这个任务对应的惩罚;直至循环结束,遍历完所有任务。最终得出的惩罚结果的和输出就为答案。

 

代码

#include<iostream>
#include<algorithm>
using namespace std;
struct job
{
    int dead;
    int penalty;
};
bool cmp(job x,job y)
{
    return x.penalty>y.penalty;
}
int main()
{
    int t=0;
    cin>>t;
    for(int i=0;i<t;i++)
    {
        int n=0;
        cin>>n;
        job *work=new job[n];
        int maxx=0;
        for(int j=0;j<n;j++)
        {
            cin>>work[j].dead;
            if(work[j].dead>maxx)
                maxx=work[j].dead; //记录最大限制时间,用于开时间槽,因为后面排序是按惩罚排的,时间错乱可以避免多排一次序
        }
        for(int j=0;j<n;j++)
            cin>>work[j].penalty;
        sort(work,work+n,cmp);
        int *times=new int[maxx+1]; //时间槽
        for(int k=0;k<=maxx;k++)    //初始化时间槽,时间从1开始,时间槽要包含最大时间,个数多1
            times[k]=0;
        long long int sum=0;
        for(int j=0;j<n;j++)
        {
            for(int k=work[j].dead;k>=1;k--)
            {
                if(times[k]==0)
                {
                    times[k]=1;
                    break;
                }
                else if(k==1)
                    sum+=work[j].penalty; //没找到空槽
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值