【贪心】Doing Homework again

Doing Homework again
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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

题目意思就是有N个作业,每个作业有时间限制(规定多少天内完成),没完成会扣分,求所扣的最低分是多少。

这题是在DP专题里面的,一直在往DP方向想,结果想不出来,然后百度题解发现都是用贪心做的……好吧,其实我已经分不清楚两者的差别了。这几天做DP题目做的很受伤,真不想百度,但就是想不出来,我还是太水了……

好吧,做题的思路有两种:

一种是按照时间排序(递增),时间相同把扣分按从大到小排。排好后搜索一遍结构体数组,设置一个变量day,从1开始,如果结构体的时间小于day,则day++,并把结构体元素标记。如果大于,则搜索一遍前面的元素里面扣分最小的,跟其比较后替换。(其实这种思路我想到了,但一直往DP上想,就没想明白怎么实现)

还有一种是按扣分排序(递减),扣分相同就把时间按递减排。排好后搜索一遍结构体数组,加一个for循环把每个元素的时间从大到小递减,搜到没标记的时间就标记,搜不到时间就把元素标记,最后把标记元素相加;

我用的是第二种,代码如下:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
using namespace std;
struct homework
{
    int t,s;
};
bool cmp(homework a,homework b)
{
    if(a.s==b.s)
    return a.t<b.t;
    return a.s>b.s;
}
homework a[1005];
int main()
{
    int t,n,i,j,flag[1005],sum;
    cin>>t;
    while(t--)
    {
        cin>>n;
       memset(flag,0,sizeof(flag));
       sum=0;
       for(i=1;i<=n;i++)
       cin>>a[i].t;
       for(i=1;i<=n;i++)
           cin>>a[i].s;
       sort(a+1,a+n+1,cmp);
       for(i=1;i<=n;i++)
       {
           int f=0;
           for(j=a[i].t;j>=1;j--)
           {
               if(flag[j]==0)
               {
                   flag[j]=1;
                   f=1;
                   break;
               }
           }
           if(f==0)
           {
               sum+=a[i].s;
           }
       }
       cout<<sum<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值