hdu1789——Doing Homework again(贪心)

Doing Homework again

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5432    Accepted Submission(s): 3207


Problem Description
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
 

Author
lcy




先说下题意,每个作业都有分数和截止日期,第一行输入样例数目,第二行作业数,后面两行是作业所占分数和作业的截止日期。

如果不能按时完成作业将要扣除相应的分数,求所能扣除的最少分数。

这是一道贪心问题,但是我刚开始做这道题的时候却没能想到一种很好的贪心策略。

首先不能单纯地按照分数的高低顺序或者截止日期顺序完成作业。这两项必须同时被考虑到,并且使得利益最大化。

最后在看别人的解题报告时才恍然大悟。其实思想十分简单,而且不证自明。

可以总结成一句话就是:从分数高的开始考虑,并安排到截止日期那天,如果没空则向前推,如果前面也没空则扣分。

哎,为什么自己当时没想到呢。委屈

代码如下:

#include<stdio.h>
struct work
{
    int time,score;
}w[1001];
int vis[1001];
int cmp(struct work *x,struct work *y)
{
    return y->score-x->score;
}
main()
{
    int x,n,i,j,t,sum;
    scanf("%d",&x);
    while(x--)
    {
        scanf("%d",&n);
        for(i=0;i<=n;i++)
            vis[i]=0;
        for(i=0;i<n;i++)
            scanf("%d",&w[i].time);
        for(i=0;i<n;i++)
            scanf("%d",&w[i].score);
        qsort(w,n,sizeof(w[0]),cmp);
        for(i=0,sum=0;i<n;i++)
        {
            t=w[i].time;
            while(vis[t]&&t>0)
                t--;
            if(t==0) sum+=w[i].score;
            else vis[t]=1;
        }
        printf("%d\n",sum);

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值