这道题看了几个小时。。
刚开始觉得毫无头绪,后来看了看别人的解题思路,才知道要用到打表。。当然啦,贪心是必不可少的!!
这道题有两种方法:分别是按未完成作业所扣的分从高到低排序和按老师所给期限从小到大排序,主要是细节,太难想了。。
我个人觉得还是第一种排序容易理解些。第一种解题思路:分数从高到低排好后,从第一个开始对天数打表,即分高的就在最后期限的当天完成。若遇天数相同的,就逐个往前推(注意:此时分数已从高到低排好序)。如果天数都相同了,那么扣除的分数就是最少的。
代码如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node{
int d,f;
}a[1001];
int b[10000];
bool cmp(node a,node b){
if(a.f==b.f)
return a.d<b.d;
return a.f>b.f;//按扣分排序,如果扣分相同,则按天数排序
}
int main(){
int t,n,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i].d);
for(int i=0;i<n;i++)
scanf("%d",&a[i].f);
sort(a,a+n,cmp);
memset(b,0,sizeof(b));//使数组b初始化为零,后面方便打表
int ans=0;
for(int i=0;i<n;i++){
for(j=a[i].d;j>0;j--){//扣分高的就在那天期限完成,如有相同的天数期限,就往前推一天
if(b[j]==0){
b[j]=1;
break;
}
}
if(j==0)//如果都相同,则扣除扣分最少的那门作业的分
ans+=a[i].f;
}
printf("%d\n",ans);
}
return 0;
}