智力大冲浪

https://loj.ac/problem/10004

题目描述

  这道题相当于给出n个任务,每个任务都有完成时间和未完成的惩罚,求出最多能获得的钱数

思路

  我们已知总钱数,那么只需要求出最少的惩罚数,再用总钱数减去惩罚钱数即可。我们考虑如何让总被惩罚的钱数最少。首先我们先把这(n)个任务按惩罚代价降序排序,为了尽量不影响后续的状态,我们选择时刻要尽可能晚,而且一个时刻只能完成一个任务,那么就可以从完成时间开始往前循环找到第一个未做过任务的时刻用来做此任务。这个贪心策略是比较显然的,因此就不加赘述了。

代码

#include <bits/stdc++.h>
using namespace std;
struct aa
{
    int d,w;
}a[550];
bool cmp(aa x,aa y)
{
    return x.w>y.w;
}
bool f[550];
int main() 
{
    int m,n;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].d);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].w);
    sort(a+1,a+n+1,cmp);
    int s=0;
    for(int i=1;i<=n;i++)
    {
        bool find=0;
        for(int j=a[i].d;j>=1;j--)
            if(!f[j])
            {
                f[j]=1;
                find=1;
                break ;
            }
        if(!find)
        {
            for(int j=n;j>=1;j--)
                if(!f[j])
                {
                    f[j]=1;
                    break ;
                }
            s+=a[i].w;
        }
    }
    printf("%d",m-s);
    return 0;
}
原文地址:https://www.cnblogs.com/fangbozhen/p/11754125.html