HDU1789(Doing Homework again)题解

HDU1789(Doing Homework again)题解

以防万一,题目原文和链接均附在文末。那么先是题目分析:

【一句话题意】

给定任务分数和其截止日期,每日可完成一任务,输出当罚分尽可能小时的最小罚分。

【题目分析】

由于写的时候就知道是贪心了(专项练习= =||),所以要设计贪心策略,但是应该先处理数据以便使用。
由于要求罚分尽可能小,那么我们就根据罚分来排序。根据罚分从大到小排序,如果罚分相同则根据日期从小到大排序。(现在想想觉得似乎日期排不排都行。。)
那么我们的贪心策略应该尽可能保证分数高的作业完成。于是我们从排好的序列依次访问,并根据其作业指定的截止日期来决定这个作业啥时候写就行了。
如果出现该日已经安排有作业了,那么只需要让这次作业提前一天写就是了。如果还是有之前安排的作业,就再提前一天。如果全满了,那么这项作业可以扔掉了。由于之前排序是根据作业分数多少排序的,所以如果这项作业被扔掉了,那么这项作业的分数一定是很低的。符合舍弃目的。

【算法流程】

结构体:

“作业”结构具有的属性为

  • 截止时间;
  • 作业权重;
  • 标记;//标记则做此作业

贪心策略:

我们先按照作业的分数来进行排序,
权重处理后根据作业时间进行处理
如果该日已有作业,则该作业提前一天写

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 
 7 typedef struct SubjectType{
 8     int deadline;
 9     int mark;
10     bool isSelected;
11 } subject;
12 
13 bool cmp(SubjectType a,SubjectType b){
14     if (a.mark != b.mark) return a.mark > b.mark;
15     return a.deadline < b.deadline;
16 }
17 
18 int main()
19 {
20     int dataCount,subjectCount;
21     int i,j,k,flag[1001];//flag用以标记该日要做的作业编号 ,0为最远天数 
22     subject arr[1001];
23     scanf("%d",&dataCount);
24     while(dataCount--){
25         memset(flag,0,sizeof(flag));
26         scanf("%d",&subjectCount);
27         arr[0].deadline = 0;
28         arr[0].mark = 0;
29         arr[0].isSelected = false;
30         for(i = 1;i<=subjectCount;i++){
31             scanf("%d",&arr[i].deadline);
32             if (arr[i].deadline>flag[0])
33                 flag[0] = arr[i].deadline;
34         }
35         for(i = 1;i<=subjectCount;i++){
36             scanf("%d",&arr[i].mark);
37             arr[i].isSelected = false;
38         }
39         sort(arr+1,arr+subjectCount+1,cmp);
40         for(i = 1;i<=subjectCount;i++){
41             j = arr[i].deadline; 
42             while(j>=1){
43                 if (flag[j] != 0) j--;
44                 else break;
45             }
46             if (j == 0) continue;
47             flag[j] = i;
48         }
49         for(i = 1;i<=flag[0];i++){
50             arr[flag[i]].isSelected = true;
51         }
52         int sum;
53         sum = 0;
54         for(i = 1;i<=subjectCount;i++){
55             if (!arr[i].isSelected)
56                 sum+= arr[i].mark;
57         }
58         //for(i = 1;i<=flag[0];i++)printf("%d_",flag[i]);
59         printf("%d\n",sum);
60     }
61     return 0;
62 }
63 /*
64 TestData(IN)
65 3
66 3
67 3 3 3
68 10 5 1
69 3
70 1 3 1
71 6 2 3
72 7
73 1 4 6 4 2 4 3
74 3 2 1 7 6 5 4
75 TestData(OUT)
76 0
77 3
78 5
79 */

 


 

这里是附带的题目信息:

题目链接:(HDU 1789)Doing Homework again
题目属性:贪心(当然,也可以用dp写)
相关题目:1009、1045、1049、1050、1051、1052、1257、1800、2037、2111、2124、2187、2391、2570
题目原文:
【Desc】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.
【In】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.
【Out】For each test case, you should output the smallest total reduced score, one line per test case.
【SampIn/Out】参见代码下方的注释。

posted @ 2014-12-19 19:18  BLumia  阅读(735)  评论(1编辑  收藏  举报