ZCMU-1587-做功课

1587: 做功课

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 21   Solved: 8
[ Submit][ Status][ Web Board]

Description

伊格内修斯刚刚参加完ACM/ ICPC比赛回来。现在,他有很多功课要做。每一位老师给他规定了功课提交的最后期限。
如果伊格内修斯的在截止日期后的递交作业,老师会减少他的最终测试得分。现在我们假设他每天都在做功
课。每门功课总是需要一天时间。现在,伊格请你帮他安排做功课,尽量减少降低分数的顺序。

Input

输入包含多个测试用例。输入的第一行是一个单一的整数t即测试用例的数目。
每个测试用例开始一个正整数N(1<= N <= 1000),其表示一共有多少门作业作业。接着两行数据。
第一行包含N个整数,表明该科目的最后期限,而下一行包含N个整数,表明了降低分数。

Output

对于每一个例子,你需要输出最少的可能降低的分数,每个测试占一行

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了,其实我dp也是菜鸡一个..网上模仿了大佬的算法,还是
要不断的去充实自己吧,言归正传,我们要求出总共要扣多少分数,然后我们求出我们最多能获得多少分数,然后用
本应该去扣的分数减去能获得的最大的分数就可以得到最少被扣到多少分了,这里我们用背包问题来求解,就是算第
j天最多能拿到多少分。需要注意的是这里读入的时间是最后的期限
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <iostream>
using namespace std;
struct E
{
    int time;
    int score;
}a[1001];
bool cmp(E b,E c)
{
    if(b.time!=c.time)
        return b.time<c.time;
    return b.score>c.score;
}
int f[100010];
int main()
{
    int t,i,j,n,sum,sum1;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        sum=0;
        sum1=0;
        memset(f,0,sizeof(f));
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i].time);
        }
        for(i=0;i<n;i++)
        {
            scanf("%d",&a[i].score);
            sum+=a[i].score;
        }
        sort(a,a+n,cmp);
        for(i=0;i<n;i++)
        {
            for(j=a[i].time;j>0;j--)
            {
               f[j]=max(f[j],f[j-1]+a[i].score);//背包问题,求第j天能获得的最大分数
            }
        }
        for(i=1;i<=a[n-1].time;i++)
        {
            sum1=max(sum1,f[i]);//求出最大的分数
        }
        printf("%d\n",sum-sum1);//所有的分数减去能获得的分数
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值