题目

传送门

题解

贪心、DP两种思路。

贪心

为了减少扣分,尽可能地按时完成扣分多的作业,按照这个思路自定义排序规则。按照扣分从多到少排序,然后每个作业的最后期限开始向第一天遍历占据时间完成作业,占据不到时间的即为无法完成。

DP

按照DP思路来考虑的话类似是一个01背包问题,把每个作业看作一件物品的话,物品的重量就是1,价值即为扣分,求解背包的最大容量,所有作业的扣分总和减去背包的最大容量即为解。按照作业完成最后期限从早到晚排序,避免晚完成的作业的状态无法向早完成的作业进行状态转移,状态转移公式为f[j] = max(f[j], f[j - 1] + h[i].score),h[i].score为排序后第i份作业的扣分。

代码

DP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <bits/stdc++.h>
using namespace std;
const int N = 1009;
int T, n;
struct Homework {
int ddl, score;
bool operator < (const Homework &a) const {
return ddl < a.ddl;
}
}h[N];
int f[N];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &h[i].ddl);
}
int sumOfScore = 0;
for (int i = 1; i <= n; i++) {
scanf("%d", &h[i].score);
sumOfScore += h[i].score;
}
memset(f, 0, sizeof(f));
sort(h + 1, h + n + 1);
int sum = 0;
for (int i = 1; i <= n; i++) {
for (int j = h[i].ddl; j >= 1; j--) {
f[j] = max(f[j], f[j - 1] + h[i].score);
sum = max(sum, f[j]);
}
}
printf("%d\n", sumOfScore - sum);
}
return 0;
}

贪心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <bits/stdc++.h>
using namespace std;
const int N = 1009;
int T, n;
struct Homework {
int ddl, score;
bool operator < (const Homework &a) const {
// if (score == a.score) {
// return ddl < a.ddl;
// }
return score > a.score;
}
}h[N];
bool f[N];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &h[i].ddl);
}
for (int i = 1; i <= n; i++) {
scanf("%d", &h[i].score);
}
memset(f, 0, sizeof(f));
sort(h + 1, h + n + 1);
int sum = 0;
for (int i = 1; i <= n; i++) {
int t = h[i].ddl;
while(f[t]) t--;
if (t <= 0) {
sum += h[i].score;
} else {
f[t] = 1;
}
}
printf("%d\n", sum);
}
return 0;
}