Problem Discription
Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test. And now we assume that doing everyone homework always takes one day. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
Input
The input contains several test cases. The first line of the input is a single integer T that is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=1000) which indicate the number of homework.. Then 2 lines follow. The first line contains N integers that indicate the deadlines of the subjects, and the next line contains N integers that indicate the reduced scores.
Output
For each test case, you should output the smallest total reduced score, one line per test case.
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
思路
本题关键在于弄清贪心的方法。根据题意,所有作业完成时间都为1天,并且超过截止时间之后扣分不会变化,即如果作业超过截止时间,就不需要再考虑其完成时间。
因此,将作业按分数降序排序,依次考虑每份作业的完成时间,尽可能延后,但不能超过截止时间。这样,就会有一些作业无法完成,将他们的扣分求和输出即可。
代码
#include<bits/stdc++.h>
using namespace std;
class homework
{
public:
homework(){}
homework(int a,int b)
{
deadline=a;
score=b;
}
int deadline;
int score;
};
bool cmp(homework h1,homework h2)
{
if(h1.score!=h2.score) return h1.score>h2.score;
else return h1.deadline<h2.deadline;
}
int main()
{
int T;
cin>>T;
while(T--)
{
int N;
cin>>N;
homework zy[N];
for(int i=0;i<N;i++) cin>>zy[i].deadline;
for(int i=0;i<N;i++) cin>>zy[i].score;
int day[N+1];//第i天完成作业day[i]
bool p[N+1];//标记作业是否完成
for(int i=0;i<=N;i++) day[i]=-1,p[i]=0;
sort(zy,zy+N,cmp);
for(int i=0;i<N;i++)//考虑第i份作业
{
int j;
for(j=zy[i].deadline;j>=1&&!p[i];j--)//能否在第j天完成
{
if(day[j]==-1)
{
day[j]=i,p[i]=1;
break;
}
}
}
int sum=0;
for(int i=0;i<N;i++) if(!p[i]) sum+=zy[i].score;
cout<<sum<<'\n';
}
}