Longest Increasing Subsequence(LIS)

博客介绍了最长上升序列(a1<a2<a3<⋯<an)和最长不下降序列(a1≤a2≤a3≤⋯≤an),指出题意可理解为求解最长上升序列,并给出两种解法,分别是动态规划和贪心+二分,还提供了详解博客链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

eg:
HDU-1257

最长上升序列
a 1 &lt; a 2 &lt; a 3 &lt; ⋯ &lt; a n a_1&lt;a_2&lt;a_3&lt; \dots &lt; a_n a1<a2<a3<<an
最长不下降序列
a 1 ≤ a 2 ≤ a 3 ≤ ⋯ ≤ a n a_1 \leq a_2 \leq a_3 \leq \dots \leq a_n a1a2a3an

题意可以理解为求解最长上升序列
两种解法

第一种使用动态规划,第二种为贪心+二分:
详解博客https://blog.csdn.net/George__Yu/article/details/75896330

#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;



void hdu1257(){
    int n;
    while(cin>>n){
        int *dis=new int [n];
        for(int i=0;i<n;i++) cin>>dis[i];

        int *d=new int [n];
        //inital
        int maxx=0;
        d[0]=1;
        
        for(int i=1;i<n;i++){
            d[i]=1;
            for(int j=0;j<i;j++){
                if(dis[i]>dis[j]){
                    d[i]=max(d[i],d[j]+1);
                }
            }
            maxx=max(maxx,d[i]);
        }
        cout<<maxx<<endl;
        delete [] dis;
        delete [] d;
    }
}

void hdu1257x(){
    int n;
    while(cin>>n){
        int *dis=new int [n];
        int *d= new int [n];
        for(int i=0;i<n;i++) {
            cin>>dis[i];
            d[i]=-1;
        }

        
        int ans=0;
        d[0]=dis[0]; //put the first node to the d
        for(int i=1;i<n;i++){
            if(d[ans]>dis[i]){
                //binary search to insert the node
                int left=-1,right=ans;
                while(right-left>1){
                    int mid=(left+right)/2;
                    if(d[mid]<dis[i]){
                        left=mid;
                    }else{
                        right=mid;
                    }
                }
                
                d[right]=dis[i]; //insert the node to array

            }else if(d[ans]<dis[i]){  //add to the next
                d[++ans]=dis[i];
            }
        }
        cout<<ans+1<<endl;
    }
    
}

int main(){
    hdu1257x();
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值