HDU 1789 Doing Homework again
题目链接:HDU 1789【Doing Homework again】
思路
将输入的数据按分数排序,先将分数高的作业完成,但是考虑到一天只能写一种作业,为了不造成冲突需要预留头几天,从每种作业的结束期限开始安排,因为所有作业都可以在头几天完成,若从第1天开始安排则可能出现如下的情况:作业分数--9, 7, 5, 3, 1,结束期限--4, 9, 32, 2, 1,此时如果从第1天开始安排作业则分数为3和1的作业不能被完成。若从结束期限开始安排作业,则留下的都是期限内分数尽可能高的作业,如:作业分数--9, 8, 7, 5, 3, 2, 1,结束期限--3, 4, 3, 3, 3, 6, 8,此时按结束期限来安排,首先安排分数高的作业,则前四天的作业分数就是,5, 7, 9, 8。
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10;
struct homework {
int deadline, score;
} ig[N];
bool vis[N];
bool cmp(struct homework a, struct homework b) {
if (a.score == b.score) {
return a.deadline < b.deadline;
}
return a.score > b.score;
}
void solve() {
memset(vis, 0, sizeof vis);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> ig[i].deadline;
}
for (int i = 1; i <= n; i++) {
cin >> ig[i].score;
}
sort(ig + 1, ig + 1 + n, cmp);
int waste = 0;
// 先将扣分最多的学科安排掉
for (int i = 1, j = 0; i <= n; i++) {
// 从后往前安排,将每个学科的作业尽量安排在靠后的时间段,前面的时间段可以多个学科共用,所以留着备用
for (j = ig[i].deadline; j >= 1; j--) {
if (vis[j] == false) {
vis[j] = true;
break;
}
}
if (j == 0) {
waste += ig[i].score;
}
}
cout << waste << endl;
}
int main() {
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}