zoukankan      html  css  js  c++  java
  • 流星雨(记忆化搜索)

    链接: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
    题意:中文,应该看得懂
    思路:将输入的每个流星开始的时间作为起点,进行搜索,找到它所能到达的最远距离(把输入的流星时间段变成一幅单向图),
    如果每个都重新搜一遍一定会超时,所以要对搜索过程进行记忆化,将搜索过程的每一结果都用数组存下来,到下次再搜索到时直接取出来用。
    代码:
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<string>
    #include<string.h>
    #include<map>
    #include<vector>
    #include<cmath>
    #include<iterator>
    #define mem(a,b) memset(a,b,sizeof(a)
    #define MOD 100000007
    #define LL long long
    #define Maxn 1000000
    const double pi = acos(-1.0);
    using namespace std;
    int n;
    int tol=0;
    int head[1001010];
    int num[1001010];
    //建图 
    struct edge{
        int next;
        int to;
    }e[Maxn*3];
    void add(int start,int ed){
        tol++;
        e[tol].next=head[start];
        e[tol].to=ed;
        head[start]=tol;
    }
    bool vis[1001010];
    int t[Maxn];
    //搜索 
    int dfs(int start){
        vis[start]=true;
        int tt=-1;
        for(int i=head[start];i;i=e[i].next){
            if(!vis[e[i].to]){//这个点没有被搜索过,进行搜索 
                int uy=dfs(e[i].to);
                //cout<<uy<<"  "<<tt<<endl;
                tt=max(tt,uy);        
            }else{//这个点已经被搜索过了,直接拿出结果来用 
                tt=max(tt,num[e[i].to]);
            }
        }
        if(tt==-1) return start;//这个点已经没有后继点了,返回这个点,这个即是离start最远的点 
        else return num[start]=tt;//这个start有一个可更新的最远终点,进行更新 
    }
    int main(){
        scanf("%d",&n);
        int start,ed;
        int u=0;
        for(int i=0;i<n;i++){
            scanf("%d%d",&start,&ed);
            add(start,ed);
            t[u++]=start;
        }
        int ans=0;
        for(int i=0;i<u;i++){
            if(!vis[t[i]]){//这个点未被计算过,进行搜索计算最远距离 
                dfs(t[i]);
                ans=max(ans,num[t[i]]-t[i]);//更新答案 
            }
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    (转)C#中的那些全局异常捕获
    mysql 5.7 MGR
    mysql 5.7 MGR
    perl 获取响应头
    python 获取响应头
    研究生开咖啡厅,年盈利15万,欲打造重庆咖啡文化
    女学生经营二手服装租赁,年营业额突破300万
    在校学生看中餐饮外送行业,企业估值500亿
    导演跨界跳入椰子水“新泳池”,一举占领椰子产品市场
    在校女学生,掌管27家卤味连锁店
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/10546856.html
Copyright © 2011-2022 走看看