<center>

问题 : 【贪心】赶作业

时间限制: 1 Sec  内存限制: 64 MB
提交: 18  解决: 12
[提交][状态][讨论版]
</center>

题目描述

小墨老师总是不及时做作业,所以他总有很多的作业要做。每个老师都给了他一个完成作业的最后期限,如果他超过期限交作业,老师就会在他的期末评价中扣分。假设做每一门作业总是要一天。小墨老师希望你能够帮助他安排做作业的一个顺序,以便能够被扣掉的分数最少。

输入

输入包含了多个测试用例。输入的第一行是一个整数T,代表测试用例的个数。接下来的就是T个测试用例的输入。每个测试用例都从一个正整数N(1≤N≤1000)开始,代表了作业的数目。接下来有2行。第一行包含N个整数,分别代表各个作业提交的最后期限;第二行也有N个整数,即对应于各个作业操过时间提交的扣分。

输出

对每一个测试用例,应该在一行中输出最小的扣分数。

样例输入

2
3
3 3 3
10 5 1
3
1 3 1
6 2 3

样例输出

0
3
解题思路:题目要求输出扣最少的分数,看的第一眼感觉非常简单,于是先按照所给的期限升序排序,然后顺着看,当所给期限早于分配到的期限时就记上这一个。结果提交不对。
然后又按照分数降序排序,再顺着看所给期限与分配到的位置,结果提交仍然不对。
最后恍然大悟,应该是自己给它分配时间,首先所扣分数按照降序排列,然后取第一个,从他所给期限的最晚时间开始安排,如果这一天已经有安排,安排到前一天。。。这样先让扣分最多的有着落,最后剩下扣分少的,才是扣最少分的正确策略。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;

struct node{
    int date;
    int score;
    int sd;
};
node subject[1005];

int cmp(node a,node b){
    //return a.date<b.date||a.date==b.date&&a.score>b.score;
    return a.score>b.score||a.score==b.score&&a.date<b.date;
    //return a.sd>b.sd;
}

int main()
{
    int t;
    int n;
    int s=0;
    int b[1005]={0};
    scanf("%d",&t);
    for(int j=0;j<t;j++){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&subject[i].date);
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&subject[i].score);
            subject[i].sd=0;
        }
        sort(subject+1,subject+n+1,cmp);
        for(int i=1;i<=n;i++){
            for(int ii=subject[i].date;ii>0;ii--){
                if(b[ii]==0){
                    b[ii]=1;
                    subject[i].sd=1;
                    break;
                }
            }
            if(subject[i].sd==0){
                s+=subject[i].score;
            }
        }

        printf("%d\n",s);
        s=0;
        memset(b,0,sizeof(b));
    }
    return 0;
}