hdu 1789 Doing Homework again

Posted huashanqingzhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 1789 Doing Homework again相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1789

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Problem Description
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

 Author
lcy
 
Source

 

题目大意:有T组测试数据,每组测试数据首先输入N表示有N门功课,然后输入一行N个整数表示完成N门功课作业的时间限制,接着输入一行N个整数表示未在限制的时间内完成作业要扣除的分数。需要求最少被扣的分数。

思路:可以用贪心算法策略解决:优先安排分数较大的功课;同时,每一门功课的作业在其截止日期到达前尽量靠后安排,这样可以把靠前的日期节约出来,安排其他更紧急的功课。

具体做法:

对分数按从大到小排序,分数相等则按截止日从小到大排。然后按分数从大到小扫描所有工作,为各项功课排档期:扫描到第i项功课时,假设第i项功课截止日为x,那么,若是第x天没有被安排其他功课,那第x天就排第i项功课;若是第x天安排了其他功课,那么就从第x-1天往前到第1天寻找一个空闲日来安排第i项功课。若是找不到空闲日,就无法安排第i项功课。若是第i项功课能被安排就接着安排下一项功课,若无法安排第i项功课,那就扣除第i项功课的分数。

具体代码如下:

 1 #include <iostream>
 2 #include<algorithm>
 3 #include<stdio.h>
 4 #include<string.h>
 5 using namespace std;
 6 
 7 #define maxN 1005
 8 
 9 struct work
10 {
11     int time,score;
12 }works[maxN];
13 bool done[maxN];
14 
15 int cmp(struct work a,struct work b)
16 {
17     if(a.score!=b.score)
18         return a.score > b.score;//按分数从大到小排序
19     else return a.time < b.time;//分数相等,截止时间小的排在前面
20 }
21 
22 int main()
23 {
24     int T,N,i,ans;
25     int j;
26     scanf("%d",&T);
27     while(T--)
28     {
29         scanf("%d",&N);
30         for(i=0;i<N;i++) scanf("%d",&works[i].time);
31         for(i=0;i<N;i++) scanf("%d",&works[i].score);
32         sort(works,works+N,cmp);
33 
34         /*for(i=0;i<N;i++) printf("%d ",works[i].score);
35         printf("
");*/
36 
37         ans=0;
38         memset(done,false,sizeof(done));
39 
40         for(i=0;i<N;i++)//按照分数从小到大的顺序扫描所有作业
41         {
42             if(done[works[i].time]==true)//如果第i项作业截止日期当天已经被占用
43             {
44                 j=works[i].time;
45                 while(j>0&&done[j]==true)//注意:时间是从1开始,第0天不存在,这里j必须大于0
46                     j--;//从截止日当天往前寻找空闲的一天来安排该项作业
47                 if(j>0)//注意:时间是从1开始,第0天不存在,这里j必须大于0
48                     done[j]=true;   //如果找到空闲天,在这一天安排该项作业
49                 else ans=ans+works[i].score;//若找不到空闲天,该项作业无法完成,相应分数被扣除。
50             }
51             else done[works[i].time]=true;//第i项作业截止日期当天没被占用,那就在截止日期安排该项作业
52         }
53         printf("%d
",ans);
54     }
55     return 0;
56 }

 

下面的代码是从网上摘抄的,可以参考一下:(来源戳这里

技术图片
 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 struct ss
 7 {
 8     int time,p;
 9 }t[100000];
10 int f[100000];
11 int cmp(const ss a,const ss b)
12 {
13     if(a.p>b.p)
14         return 1;
15     else if(a.p==b.p&&a.time<b.time)
16         return 1;
17     else
18         return 0;
19 }
20 int main()
21 {
22     int text,n;
23     scanf("%d",&text);
24     while(text--)
25     {
26         scanf("%d",&n);
27         memset(f,0,sizeof(f));
28         int i;
29         for(i=1;i<=n;i++)
30             scanf("%d",&t[i].time);
31         for(i=1;i<=n;i++)
32             scanf("%d",&t[i].p);
33         sort(t+1,t+1+n,cmp);
34         int sum=0;
35         for(i=1;i<=n;i++)
36         {
37             for(int j=t[i].time;j>=1;j--)
38                 if(!f[j])
39                 {
40                     f[j]=1;
41                     break;
42                 }
43             if(j==0)
44                 sum+=t[i].p;
45         }
46         printf("%d
",sum);
47     }
48     return 0;
49 }
View Code

 

以上是关于hdu 1789 Doing Homework again的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1789 Doing Homework again(贪心)

HDU 1789 Doing Homework again

hdu 1789 Doing Homework again

hdu 1789 Doing Homework again 贪心

HDU 1789 - Doing Homework again - [贪心+优先队列]

HDU 1789 Doing Homework again