ZJM 有 n 个作业,每个作业都有自己的 DDL,如果 ZJM 没有在 DDL 前做完这个作业,那么老师会扣掉这个作业的全部平时分。
所以 ZJM 想知道如何安排做作业的顺序,才能尽可能少扣一点分。
请你帮帮他吧!
Input
输入包含T个测试用例。输入的第一行是单个整数T,为测试用例的数量。
每个测试用例以一个正整数N开头(1<=N<=1000),表示作业的数量。
然后两行。第一行包含N个整数,表示DDL,下一行包含N个整数,表示扣的分。
Output
对于每个测试用例,您应该输出最小的总降低分数,每个测试用例一行。
Sample Input
3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4
Sample Output
0
3
5
思路
依旧贪心。先贪的是分数尽量高,将每个作业按照成绩排序后,我们先完成成绩高的作业。第二贪心的是对其他作业的影响最少,我们将一个作业在某一时间ti完成的时候,影响到的是ddl在ti之后的作业,因为占用了它们的空闲时间,对于ddl在ti之前的作业不受影响,因为它们必须完成的那些时间段并不包含ti。所以要想影响的作业最少,我们按每个作业ddl开始往前寻找空闲时间,一找到就完成,最后求完成的分数与总分数的差。
代码
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct homework{
int ddl;
int score;
}hw[1005];
int time[100000];
int cmp(homework a,homework b)
{
return a.score!=b.score? a.score<b.score:a.ddl<b.ddl;
}
int main()
{
int T;
cin>>T;
for(int i=0;i<T;i++)
{
int n;
cin>>n;
int sum=0;
for(int j=0;j<n;j++)
{
cin>>hw[j].ddl;
}
for(int j=0;j<n;j++)
{
cin>>hw[j].score;
}
sort(hw,hw+n,cmp);
memset(time,0,sizeof(time));
for(int j=n-1;j>=0;j--)
{
for(int k=hw[j].ddl;k>=1;k--)
{
if(time[k]==0)
{
time[k]=1;
sum+=hw[j].score;
break;
}
}
}
int total=0;
for(int j=0;j<n;j++)
{
total+=hw[j].score;
}
cout<<total-sum<<endl;
}
return 0;
}