【贪心】家庭作业 【链表优化】

题目描述
老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为10,要求在6天内交,那么要想拿到这10学分,就必须在第6天结束前交。
每个作业的完成时间都是只有一天。例如,假设有7次作业的学分和完成时间如下:

老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为10,要求在6天内交,那么要想拿到这10学分,就必须在第6天结束前交。
每个作业的完成时间都是只有一天。例如,假设有7次作业的学分和完成时间如下:

 

输入
第一行一个整数N,表示作业的数量;
接下来N行,每行包括两个整数,第一个整数表示作业的完成期限,第二个数表示该作业的学分。

 

输出
输出一个整数表示可以获得的最大学分。保证答案不超过C/C++的int范围。

 

样例输入

复制样例数据

7
1 6
1 7
3 2
3 1
2 4
2 5
6 1
样例输出
15

 

提示

对于20%的数据,N≤103;
对于40%的数据,N≤104;
对于60%的数据,N≤105;
对于100%的数据,N≤106,作业的完成期限均小于7×105

 
分析:
优先选择分高的,所以先根据分数从高到低排序,然后预处理链表为:每一天指向最近的空闲的前一天
然后遍历一次 若可以 则更新链表
 
代码:
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1000005;
int pre[maxn];
bool vis[maxn]={0};

struct node{
    int d,v;
}a[maxn];
int cmp(node x,node y)
{
    if(x.v!=y.v)
        return x.v>y.v;
    else
        return x.d>y.d;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}

int findfa(int x)
{
    if(!vis[x])
        return x;
    else
        return pre[x] = findfa(pre[x]);
}

int main(){
    int n;
    n = read();
    for(int i=0;i<n;i++){
        a[i].d = read();
        a[i].v = read();
    }
    sort(a,a+n,cmp);
    for(int i=1;i<=700000;i++)
        pre[i] = i-1;
    int ans = 0;
    int pre_pos;
    for(int i=0;i<n;i++)
    {
        pre_pos = findfa(a[i].d);
        if(pre_pos==0)
            continue;
        else
        {
            vis[pre_pos] = 1;
            ans+=a[i].v;
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/hao-tian/p/10392399.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值