hdu 5747 最长上升子序列 (nlogn)

ac code:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
#define INF 1e9
#define maxn 100005
int a[maxn];              //记录原序列
int d[maxn];              //d[k] 表示长度为k的上升子序列结尾的最小值
int f[maxn];              //f[t] 表示以a[t]结尾的上升子序列的最大长度

int main()
{
    int n,m;
    int cas;
    cin >> cas;
    while(cas --){
        cin >> n;
        for(int i = 1;i <= n;i ++){
            cin >> a[i];
        }
        //nlogn 的dp 求最长公共子串
        for(int i = 1;i <= n;i ++){
            d[i] = INF;
            f[i] = 1;
        }
        int nowK = 1;
        for(int i = 1;i <= n;i ++){
            int l,r;
            l = 1;
            r = i+1;
            while(l <= r){
                int m = (l+r)/2;
                if(a[i] > d[m]) l = m + 1;
                else r = m - 1;
            }
            f[i] = l;
            d[l] = a[i];
        }
        for(int i = 1;i <= n-1;i ++)
            printf("%d ",f[i]);
        printf("%d\n",f[n]);
    }
    return 0;
}

时间: 2024-12-13 09:10:01

hdu 5747 最长上升子序列 (nlogn)的相关文章

hdu 1025 Constructing Roads In JGShining&#39;s Kingdom(最长上升子序列nlogn算法)

学习了最长上升子序列,刚开始学的n^2的方法,然后就超时了,肯定超的,最大值都是500000,平方之后都12位 了,所以又开始学nlogn算法,找到了学长党姐的博客orz,看到了rating是浮云...确实啊,这些不必太关 注,作为一个动力就可以啦.没必要看的太重,重要的事学习知识. 思路: 这道题目可以先对一行排序,然后对另一行求最长上升子序列... n^2算法: 序列a[n],设一个数组d[n]表示到n位的时候最长公共子序列(此序列包括n),所以呢 d[n]=max(d[j]+1,0<j<

POJ 1631(最长上升子序列 nlogn).

~~~~ 由题意可知,因为左边是按1~n的顺序递增排列,要想得到不相交组合,左边后面的一定与相应右边后面的相连,如此一来, 就可以发现其实是一道最长上升子序列的题目,要注意的是N<40000,用n^2的算法一定会超时. 题目链接:http://poj.org/problem?id=1631 ~~~~ nlogn的算法在这里补充一下. 最长不下降子序列的O(nlogn)算法分析如下: 设 A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F [t]

最长上升子序列 nlogn

最长上升子序列中对于数ipt[i],向前遍历,当数ipt[j]小于ipt[i] 则ipt[j]可作为上升序列中ipt[i]的前一个数字 dp[i] = max{ dp[j] + 1 | j < i && ipt[j] < ipt[i]} 若现在有两个状态a,b 满足dp[a] = dp[b]且 ipt[a] < ipt[b]  则对于后面的状态dp[a]更优  因为若ipt[i] > dp[b] 则必然ipt[i] > dp[a],反之若ipt[i] >

hdu 1950 最长上升子序列

1 //Accepted 3540 KB 62 ms 2 //dp 最长上升子序列 3 #include <cstdio> 4 #include <cstring> 5 #include <iostream> 6 using namespace std; 7 const int imax_n = 400005; 8 int dp[imax_n]; 9 int d[imax_n]; 10 int a[imax_n]; 11 int n; 12 int len; 13 in

HDU 1243 最长公共子序列

反恐训练营 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2850    Accepted Submission(s): 648 Problem Description 当今国际反恐形势很严峻,特别是美国“9.11事件”以后,国际恐怖势力更是有恃无恐,制造了多起骇人听闻的恐怖事件.基于此,各国都十分担心恐怖势力会对本国社会造成的不稳定,

hdu 5773 最长递增子序列 (nlogn)+贪心

The All-purpose Zero Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 947    Accepted Submission(s): 453 Problem Description ?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] &l

最长公共子序列 nlogn

先来个板子 #include<bits/stdc++.h> using namespace std; const int N = 1e6+20, M = 1e6+10, mod = 1e9+7, inf = 1e9+1000; typedef long long ll; struct node { int c; int num; } u[N]; int i,j,k = 0,n,m,x,y = 0,T = 0,ans = 0,big = 0,cas = 0,num = 0,len = 0; bo

HDU 1025 最长上升子序列

首先根据第一个数排序,然后可以得到一串第二个数组成的序列,因为第一个由大到小排列,所以第二组中取到的数据,后面的不能比前面的小才不会形成交叉,那么也就是求这个新序列的最长公共子序列 这里要用到最长上升子序列的nlogn的算法,新建一个数组保存所有合理的数据的数组g,比如g数组中有了1,4,6,加进来一个3 , 那么4可以被3代替因为在同一个位置尽可能小能容纳的数据个数就会越多,越能找到更长的序列,这个找位置的过程就用二分搜索logn的复杂度 注意一点,我是因为这个好久没做出....就是边数大于1

LIS最长上升子序列 (nlogn) poj1631

问题描述:LIS(Longest Increasing Subsequence)最长上升(不下降)子序列,有两种算法复杂度为O(n*logn)和O(n^2).在上述算法中,若使用朴素的顺序查找在D1..Dlen查找,由于共有O(n)个元素需要计算,每次计算时的复杂度是O(n),则整个算法的时间复杂度为O(n^2),与原来算法相比没有任何进步.但是由于D的特点(2),在D中查找时,可以使用二分查找高效地完成,则整个算法时间复杂度下降为O(nlogn),有了非常显著的提高.需要注意的是,D在算法结束