• (算法)最长重叠线段或区间


    题目:

    X轴上有N条线段,每条线段包括1个起点和终点。线段的重叠是这样来算的,[10 20]和[12 25]的重叠部分为[12 20]。
    给出N条线段的起点和终点,从中选出2条线段,这两条线段的重叠部分是最长的。输出这个最长的距离。如果没有重叠,输出0。
     

    思路:

    1、暴力计算

    依次计算两两线段之间的重叠长度,但复杂度太高

    2、动态规划

    假设S[n]表示n条线段中最长重叠距离,最长重叠距离只与两条线段有关,那么考虑两种情况:

    1. 最长重叠距离与第n条线段无关,则最长重叠距离存在于前n-1条线段中,即S[n]=S[n-1];

    2. 最长重叠距离与第n条线段有关,则最长重叠距离为第n条线段与前面n-1条线段中的最大重叠距离者,S[n]=max(overlap(segment[n],segment[i])), i=1....n-1

    因此得到状态转移方程:

    S[n]=0; n<=1

    S[2]=overlap(segment[0],segment[1])

    S[n]=max(S[n-1],max(overlap(segment[n],segment[i])))

    代码:

    动态规划:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    
    typedef struct{
        int start;
        int end;
    }segment;
    
    bool isShorter(const segment &s1,const segment &s2);
    int commonSegment(const segment &seg_a,const segment &seg_b);
    int findLongestSegment(const vector<segment> &segments,int size);
    
    int main()
    {
        int n;
        int start,end;
        while(cin>>n){
            vector<segment> segments(n);
            for(int i=0;i<n;i++){
                if(cin>>start && cin>>end){
                    segments[i].start=start;
                    segments[i].end=end;
                }
            }
    
            // sort by segment.end
    //        sort(segments.begin(),segments.end(),isShorter);
    
            int maxLen;
    
            maxLen=findLongestSegment(segments,n);
    
            cout<<"Longest Length:"<<maxLen<<endl;
        }
    
        return 0;
    }
    
    bool isShorter(const segment &s1,const segment &s2){
        return s1.end<s2.end;
    }
    
    
    //assume seg_a.end<seg_b.end
    int commonSegment(const segment &seg_a,const segment &seg_b){
        segment commonSeg;
        if(seg_a.end<seg_b.start || seg_a.start>seg_b.end){
            commonSeg.start=0;
            commonSeg.end=0;
        }
        else{
            commonSeg.start=max(seg_a.start,seg_b.start);
            commonSeg.end=min(seg_a.end,seg_b.end);
        }
        return commonSeg.end-commonSeg.start;
    }
    
    int findLongestSegment(const vector<segment> &segments,int size){
        vector<int> lens(size+1);
        lens[0]=0;
        lens[1]=0;
        lens[2]=commonSegment(segments[0],segments[1]);
    
        int tmpLen;
        // size>2
        // dynamic programming
        for(int i=3;i<=size;i++){
            lens[i]=lens[i-1];
            for(int j=0;j<i-1;j++){
                tmpLen=commonSegment(segments[i-1],segments[j]);
                cout<<tmpLen<<endl;
                lens[i]=max(lens[i],tmpLen);
            }
        }
        for(int i=0;i<size+1;i++)
            cout<<lens[i]<<endl;
        return lens[size];
    }
    

    递归方法:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    
    typedef struct{
        int start;
        int end;
    }segment;
    
    bool isShorter(const segment &s1,const segment &s2);
    segment commonSegment(const segment &seg_a,const segment &seg_b);
    int findLongestSegment(const vector<segment> &segments,int size,segment &maxSegment);
    
    int main()
    {
        int n;
        int start,end;
        while(cin>>n){
            vector<segment> segments(n);
            for(int i=0;i<n;i++){
                if(cin>>start && cin>>end){
                    segments[i].start=start;
                    segments[i].end=end;
                }
            }
    
            // sort by segment.end
            //sort(segments.begin(),segments.end(),isShorter);
    
            segment maxSeg;
            int maxLen;
    
            maxLen=findLongestSegment(segments,n,maxSeg);
    
            cout<<"Longest Length:"<<maxLen<<endl;
            cout<<"start:"<<maxSeg.start<<endl;
            cout<<"end:"<<maxSeg.end<<endl;
        }
    
        return 0;
    }
    
    bool isShorter(const segment &s1,const segment &s2){
        return s1.end<s2.end;
    }
    
    
    //assume seg_a.end<seg_b.end
    segment commonSegment(const segment &seg_a,const segment &seg_b){
        segment commonSeg;
        if(seg_a.end<seg_b.start || seg_a.start>seg_b.end){
            commonSeg.start=0;
            commonSeg.end=0;
        }
        else{
            commonSeg.start=max(seg_a.start,seg_b.start);
            commonSeg.end=min(seg_a.end,seg_b.end);
        }
        return commonSeg;
    }
    
    int findLongestSegment(const vector<segment> &segments,int size,segment &maxSegment){
        if(size<=1)
            return 0;
    
        if(size==2){
            maxSegment=commonSegment(segments[0],segments[1]);
            return maxSegment.end-maxSegment.start;
        }
    
        // size>2
        // recursive method
        int maxLen,tmpLen;
        segment tmpMaxSeg;
        maxLen=findLongestSegment(segments,size-1,tmpMaxSeg);
        maxSegment=tmpMaxSeg;
    
        // maxSegment=(maxSegment,commonSeg)
        segment commonSeg;
        for(int i=0;i<size-1;i++){
            commonSeg=commonSegment(segments[i],segments[size-1]);
            tmpLen=commonSeg.end-commonSeg.start;
            if(tmpLen>maxLen){
                maxLen=tmpLen;
                maxSegment=commonSeg;
            }
        }
    
        return maxSegment.end-maxSegment.start;
    }
    

      

    运行结果:

     
  • 相关阅读:
    Java EE 经验
    Java界面设计 Swing(1)
    Java开源库
    Java Abstract Class & Interface
    Selenium WebDriver Code
    Json在PHP与JS之间传输
    Live YUV420 和 OpenCV Mat 的互相转换
    Visual C++ 升级到 Visual Studio
    Sentiment Analysis resources
    C# XMLDocument
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4537376.html
Copyright © 2020-2023  润新知