HDU - 1789 Doing Homework again(贪心) ~~~学了一波sort对结构体排序

  题目中因为天数和分数是对应的,所以我们使用一个结构体来存分数和截止如期。

  一开始做这道题的时候,很自然的就想到对天数排序,然后天数一样的分数从大到小排序,最后WA了之后才发现没有做到“舍小取大”的贪心。所以改变一下策略,对分数排序,如果分数一样的话,时间从小到大排序(因为我们的目的就是先做分多的作业,所以分数一样的得放到前几天去做)。

  (具体sort排结构体知识见代码里面,其实也可以写两次for来排序);

  思路:排好序之后,从小到大遍历,每找到一个分数,去寻找对应的天数到第一天中有没有空余的天数(因为要先做分多的),实现寻找空余天数就是从那一天往第一天遍历(((①))),遍历啥子???当然定义一个标记数组来记录你哪一天用来做作业了。如果有空余天就让他在那一天过,如果没有空余天,就是完不成的了,累计加起来,最后输出结果即可。

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <queue>
 4 
 5 #include <cstdio>
 6 #include <cstdlib>
 7 #include <cmath>
 8 #include <cstring>
 9 using namespace std;
10 
11 struct ss {
12     int time, p;
13 }t[1010];
14 
15 int cmp (const ss a, const ss b) {
16     // if (a.p>b.p) {
17         // return 1;
18     // } else if (a.p==b.p&&a.time<b.time) {
19         // return 1;
20     // } else {
21         // return 0;
22     // }
23     
24     // 两种方法都可以
25     
26     if (a.p != b.p) {
27         return a.p > b.p;
28     } else {
29         return a.time < b.time;
30     }
31 }
32 
33 bool used[1010];
34 
35 int main() {
36     int T, num;
37     cin >> T;
38     while (T--) {
39         int res = 0;
40         cin >> num;
41         for (int i = 0; i < num; ++i) {
42             scanf ("%d", &t[i].time);
43         }
44         for (int i = 0; i < num; ++i) {
45             scanf ("%d", &t[i].p);
46         }
47         sort (t, t+num, cmp);
48         memset (used, false, sizeof(used));
49         
50         int j;
51         for (int i = 0; i < num; ++i) {
52             for (j = t[i].time; j > 0; --j) {
53                 if (!used[j]) {
54                     used[j] = true;
55                     break;
56                 }
57             }
58             if (j == 0) {
59                 res += t[i].p;
60             }
61         }
62         cout << res << endl;
63     }
64     return 0;
65 }
View Code

 

思考:①处为什么不可以从第一天遍历?

答:如果从第一天遍历的话,那么很可能把只有一天的交作业时间的科目占用了,后面有空余的天,也是达不到扣最少分的结果的。

转载于:https://www.cnblogs.com/Ddlm2wxm/p/6727267.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值