题意
ZJM 有 n 个作业,每个作业都有自己的 DDL,如果 ZJM 没有在 DDL 前做完这个作业,那么老师会扣掉这个作业的全部平时分。
所以 ZJM 想知道如何安排做作业的顺序,才能尽可能少扣一点分。
请你帮帮他吧!
Input
输入包含T个测试用例。输入的第一行是单个整数T,为测试用例的数量。
每个测试用例以一个正整数N开头(1<=N<=1000),表示作业的数量。
然后两行。第一行包含N个整数,表示DDL,下一行包含N个整数,表示扣的分
思路
将n个deadline根据分数从大到小排列
用day数组来标记deadline有没有被安排
对于第i个deadline,根据ti从后往前遍历,遇到空闲的天数就将其标记,如果没有空闲的天数就表明要放弃这个deadline,要扣第i个deadline的分数
总结
设计贪心算法的时候,要考虑贪心准则的正确性,这个题贪心的准则是选择一个分数最多的,并且对后面的deadline影响最小的deadline
代码
#include <stdio.h>
#include <cstdio>
#include <algorithm>
using namespace std;
int sum;
int ans;
int day[1005];
struct ddl
{
int time;
int score;
ddl() {}
ddl(int _t,int _s)
{
time = _t;
score = _s;
}
};
bool cmp(const ddl &a,const ddl &b)
{
return b.score<a.score;
}
int main()
{
int T;
scanf("%d",&T);
for (int i = 0; i < T; i++)
{
int sum = 0;
int ans = 0;
int N;
scanf("%d",&N);
//ddl *test = new ddl[N];
ddl test[N];
for (int j = 0; j < N; j++)
scanf("%d",&test[j].time);
for (int j = 0; j < N; j++)
{
scanf("%d",&test[j].score);
sum = sum + test[j].score;
}
sort(test,test+N,cmp);
for (int j = 0; j < N; j++)
{
for (int k = test[j].time; k > 0; k--)
{
if(day[k] == 0)
{
day[k] = test[j].score;
ans = ans + test[j].score;
break;
}
}
}
ans = sum - ans;
for (int i = 0; i < 1005; i++)
day[i] = 0;
printf("%d\n",ans);
}
return 0;
}