Doing Homework again【暑期集训R题】【DP】【哈希】

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.
InputThe 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. 
OutputFor 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

    这道题的思维与DP的关系倒是不大,说实话,我觉得用到的贪心思想会多一些,之后的对于要写的作业的放置顺序会更加的贴近哈希算法。

    思路:我们能够得到这样的一串没有排过序的紊乱的截止日期与不做完就要扣的分数,我们要尽所能使得扣分少一些,那么,我想到的就是,把分数最高的开始,我们对于作业分数降序排列,而且让高分刚好掐在它的截止日期上,这样才能给后面的分数段留足空间,但遇到截止日期上刚好被其他数霸占了,那么说明这个数优先级要低,但又比剩下的数优先级高,遇到这种情况,我们把它往前提1,若不为空继续提1,但要是都满了,这个数就只能舍弃了。

完整代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
    int a,b;        //a指截止日期,b指扣分数
}k[1005];
int vis[1005];
bool cmp(node r1, node r2)
{
    return r1.b==r2.b?(r1.a>r2.a):(r1.b>r2.b);
}
int N;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int sum=0;
        memset(vis, 0, sizeof(vis));
        scanf("%d",&N);
        for(int i=0; i<N; i++)
        {
            scanf("%d",&k[i].a);
        }
        for(int i=0; i<N; i++)
        {
            scanf("%d",&k[i].b);
        }
        sort(k, k+N, cmp);
        for(int i=0; i<N; i++)
        {
            for(int j=k[i].a; j>0; j--)
            {
                if(!vis[j])
                {
                    vis[j]=1;
                    break;
                }
                else if(j==1)
                {
                    sum+=k[i].b;
                }
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值