牛客 流星雨(dp)

链接:https://ac.nowcoder.com/acm/contest/547/D
来源:牛客网

英仙座流星雨(学名Perseids)是以英仙座γ星附近为辐射点出现的流星雨,也称英仙座γ流星雨。每年在7月20日至8月20日前后出现,于8月13日达到高潮。与象限仪座流星雨、双子座流星雨并称为北半球三大流星雨。

暑假到了,又是一个去看流星雨的好季节。

看流星雨最重要的是什么?当然是许愿。

当一颗流星出现时,可以对其许愿。

你一次可以选择一颗流星进行许愿,每一个愿望都需要一定的时间才能说完,而且中间不能有中断。
但是流星的持续时间通常都很短,很难在流星消失之前把自己的一个愿望说完。
你可以朝着新出现的流星接着许上一个未许完的愿望,当且仅当前一颗流星消失的瞬间另外一颗流星同时出现,
你不可以在一颗流星还在出现的时候转向其他的流星,这样流星之神会生气,厄运会降临
现在给你每颗流星出现和结束的时间,问你许一个愿望的最大时长是多少?

输入描述:
第一行一个数n n<=1000000

表示流星的数目

接下来每行2个数字 x,y (0<=x,y<=1001000 )

表示流星出现的时间和结束的时间
输出描述:
一个数字,表示最长可以连续许愿的时间
示例1
输入
复制
3
2 3
2 4
1 2
输出
复制
3
说明
1~4

解析

是一道比较简单的dp
用dp[i]表示i可以延伸到的最小的位置即可
状态转移方程为
dp[app[i].r]=min(dp[app[i].r],dp[app[i].l]);
对结构体排序只要按照(l或者r)从小打大即可
因为每一次状态转移方程用到的l和r都是比当前小的

#include<bits/stdc++.h>
using namespace std;
const int N=1000000+1100;
int dp[N],no[N];
struct node{
    int l,r;
}app[N];
bool cmp(node a,node b){
    return a.r<b.r;
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>app[i].l>>app[i].r;
        dp[app[i].l]=app[i].l;
        dp[app[i].r]=app[i].l;
    }
    sort(app,app+n,cmp);
    int mx=0;
    for(int i=0;i<n;i++) {
        dp[app[i].r]=min(dp[app[i].r],dp[app[i].l]);
        mx=max(app[i].r-dp[app[i].r],mx);
    }
    cout<<mx<<endl;
    return 0;
}




java超时版本。。。

package myproject;
import java.io.BufferedReader;
import java.io.*;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
class node implements Comparable<node>
{
 
    int l,r;
    public node(int l,int r) {
        this.l=l;
        this.r=r;
    }
    public int compareTo(node o) {
            return this.l-o.l;
    }
     
}
public class Main {
    static int N=1000000+1100;
    static int []dp=new int [N];
    static node []no=new node [N];
    //dp[i]表示i最早的起点
    public static void main(String []args) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String str=br.readLine();
        int n=Integer.parseInt(str);
        for(int i=0;i<n;i++) {
            str=br.readLine();
            String []s=str.split(" ");
            int x =Integer.parseInt(s[0]);
            int y=Integer.parseInt(s[1]);
            no[i]=new node(x,y);
            dp[x]=x;
            dp[y]=x;
        }
        Arrays.sort(no,0,n);
        int max=0;
        for(int i=0;i<n;i++) {
            dp[no[i].r]=Math.min(dp[no[i].r],dp[no[i].l]);
            max=Math.max(no[i].r-dp[no[i].r],max);
        }
        System.out.println(max);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值