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
  • 相关阅读:
    日志
    mysql锁
    慢查询
    auto_increment
    脚本
    服务器元数据
    复制表及表数据
    临时表
    (一)校园信息通微信小程序从前端到后台整和笔记
    OpenCart框架运行流程介绍opencart资料链接
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6661559.html
Copyright © 2011-2022 走看看