HDU 1789 Doing Homework again(贪心)

来源:互联网 发布:李宁淘宝代理 编辑:程序博客网 时间:2024/05/16 11:24

Doing Homework again

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


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
333 3 310 5 131 3 16 2 371 4 6 4 2 4 33 2 1 7 6 5 4
 
Sample Output
035
 
Author
lcy
 
Source
2007省赛集训队练习赛(10)_以此感谢DOOMIII





题意:有n个作业要做,每个作业都有最后期限和将会损失的分数,求该学生能够损失的最少的分数为多少。


心得:首先开始做这个题的时候,我的第一想法是先选择分数大的做(这或许也是大多数人的第一想法),但是很快就会发现这样做的结果,连样例都过不了,这种想法是典型的错误想法。自己找个很简单的例子,就能证明这个想法的错误性。这里就不举例证明了,相信聪明的读者已经领悟到了。


分析:本题也算一个经典的一类问题的代表,本题的想法是,先把所有的作业按分数从大到小排列,然后依次把从分数最大的开始安排,如果该作业的最后期限没有被占用的话,就把这个作业安排到它的最后期限上,并把这一天标记已被占用,如果它的最后期限被占用了,就把这个作业安排到最后期限的前一天安排,再看前一天是否被占用,依次重复这个过程,如果该作业最后期限前面的时间都被占用了,那就表明这个作业的分数要被扣去。重复上面的过程,直到所有的作业安排一遍,即可求出要扣去的最少分数。






AC代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <string>#include <cmath>#include <cstdlib>#include <ctime>#define INF 0x7fffffffusing namespace std;const int maxn = 1000 + 10;typedef struct{ int work,deadline; }W;W w[maxn];int vis[maxn];bool cmp(W a,W b){    return a.work > b.work;}int main(){    int T,n,ans;    scanf("%d",&T);    while(T--)    {        ans = 0;        memset(vis,0,sizeof(vis));        scanf("%d",&n);        for(int i = 0; i < n; i++)            scanf("%d",&w[i].deadline);        for(int i = 0; i < n; i++)            scanf("%d",&w[i].work);        sort(w,w+n,cmp);        for(int i = 0; i < n; i++)        {            int t = w[i].deadline;            if(!vis[t])  vis[t] = 1;            else            {                int flag = 0;                for(int j = t-1; j > 0; j--)                {                    if(!vis[j])  { flag = 1; vis[j] = 1; break; }                }                if(!flag)  ans += w[i].work;            }        }        printf("%d\n",ans);    }    return 0;}





0 0