zoukankan      html  css  js  c++  java
  • HDU5748---(记录每个元素的 最长上升子序列 nlogn)

    分析:

    给一个序列,求出每个位置结尾的最长上升子序列

    O(n^2) 超时

    #include "cstdio"
    #include "algorithm"
    #define N 1005
    #define INF 0X3f3f3f3f
    using namespace std;
    int a[N];
    int dp[N];
    void solve(int n)
    {
        for(int i=0;i<n;i++)
        {
            dp[i]=1;
            for(int j=0;j<i;j++)///往前找寻美妙的回忆
            {
                if(a[j]<a[i])
                {
                    dp[i]=std::max(dp[i],dp[j]+1);
                }
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i==0)
                printf("%d",dp[0]);
            else
                printf(" %d",dp[i]);
        }
        printf("
    ");
    }
    
    int main()
    {
        int t,n;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
            solve(n);
        }
    }

    优化为O(nlogn)  AC

    #include "cstdio"
    #define N 100005
    #include "algorithm"
    using namespace std;
    int n;
    int a[N];
    int dp[N];
    int ans[N];
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&a[0]);
            int top=1;///最长上升子序列长度
            dp[1]=a[0];///=最后一个元素
            ans[0]=top;///每个位置的 最长上升..长度
            
            for(int j=1;j<n;j++)///对每个元素
            {
                scanf("%d",&a[j]);
                if(a[j]>dp[top])///变长
                {
                    top++;
                    dp[top]=a[j];
                    ans[j]=top;
                }
                else
                {
                    int pos=lower_bound(dp,dp+top,a[j])-dp;///二分查找位置 替换元素
                    dp[pos]=a[j];
                    ans[j]=pos;
                }
            }
            for(int i=0;i<n;i++)
            {
                if(i==0)
                    printf("%d",ans[i]);
                else
                    printf(" %d",ans[i]);
            }
            printf("
    ");
        }
    }

     若只要最长...,只输出ans[n-1]

    可将上述解法当做一模板

    #include <iostream>  
    #include <stdio.h>  
    #include <algorithm>  
    #include <string.h>  
    using namespace std;  
    int dp[20];  
    const int inf=0x7fffffff;  
    int a[7]={2,1,3,4,8,5,9};  
    const int maxn=500005;  
    int main()  
    {  
        fill(dp,dp+7,inf);  
        for(int i=0;i<7;i++)  
        {  
            *lower_bound(dp,dp+7,a[i])=a[i];  
        }  
        int len=lower_bound(dp,dp+7,inf)-dp;  
        for(int i=0;i<len;i++)  
            cout<<dp[i]<<endl;  
        return 0;  
    }
    View Code
  • 相关阅读:
    精心总结的Linux运维面试题汇总
    [DevExpress]DxValidationProvider分享
    PivotGridField 中对Unbound的列赋值(除法)--数据钻取
    PivotGridField 中对Unbound的列赋值(除法)
    2020后端/前段开发工程师应当掌握的专业技能一览(源自github)
    跨域的CRUD
    水印图片和文字
    导入 导出 压缩 解压
    winForm的CRUD 加上传图片 的DAL
    winForm的CRUD 加上传图片
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6661559.html
Copyright © 2011-2022 走看看