hdu1025 最大递增子序列

把题意转换一下就是最大递增子序列问题   不过就是数的排列不是按输入顺序

500000果断用n*logN的时间复杂度

这个算法是把每个数一个个往里面插入  然后一步步更新len(当前最大子序列)  最后得出全局的最大子序列

num【i】表示数i出现的位置  dis【k】表示子序列长度为k的出现的最小的位置(比如x=dis【k】表示最先出现子序列为k的位置为x)

注意for循环跑到i表示以num【i】结尾的最大子序列

现在就出现两种情况

1》dis【len】<num【i】 这个好说  直接令len++   然后令dis【len】=num【i】;

2》dis【len】》num【i】 然后用二分查找到最小的j是dis【j】>num【i】;令dis【j】=num【i】 注意讨论没有的情况

下面是详细代码

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

int dis[500010],num[500010];
int main()
{
    int n,i,j,a,b,d=1;
    while(~scanf("%d",&n))
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&b);
            num[a]=b;
        }
        int len=1;
        int L,R;
        dis[1]=num[1];
        for(i=2;i<=n;i++)
        {
            if(dis[len]<num[i])
            {
                len++;
                dis[len]=num[i];
            }
            else if(dis[len]>num[i])
            {
                L=1;
                R=len;
                int flash=0;
                while(L<=R)
                {
                    int mid=(L+R)/2;
                    if(dis[mid]<num[i]) L=mid+1;
                    else if(dis[mid]>num[i])R=mid-1;
                    else {flash==1;break;}
                }
                if(!flash)dis[L]=num[i];
            }
        }
        printf("Case %d:\n",d++);
        if(len==1)  printf("My king, at most 1 road can be built.");
        else    printf("My king, at most %d roads can be built.",len);
        printf("\n");
        printf("\n");
    }
    return 0;
}
时间: 2024-10-12 05:21:08

hdu1025 最大递增子序列的相关文章

HDU 3998 Sequence (最长递增子序列+最大流SAP,拆点法)经典

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1666    Accepted Submission(s): 614 Problem Description There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequ

算法面试题 之 最长递增子序列 LIS

找出最长递增序列 O(NlogN)(不一定连续!) 参考 http://www.felix021.com/blog/read.php?1587%E5%8F%AF%E6%98%AF%E8%BF%9E%E6%95%B0%E7%BB%84%E9%83%BD%E6%B2%A1%E7%BB%99%E5%87%BA%E6%9D%A5 我就是理解了一下他的分析 用更通俗易懂的话来说说题目是这样 d[1..9] = 2 1 5 3 6 4 8 9 7 要求找到最长的递增子序列首先用一个数组b[] 依次的将d里面

[dp]最长单调递增子序列

https://www.51nod.com/tutorial/course.html#!courseId=12 解题关键: 如果将子序列按照长度由短到长排列,将他们的最大元素放在一起,形成新序列B{b1,b2,……bj},则序列B满足b1 < b2 < …… <bj.这个关系比较容易说明,假设bxy表示序列A中长度为x的递增序列中的第y个元素,显然,如果在序列B中存在元素bmm > bnn,且m < n则说明子序列Bn的最大元素小于Bm的最大元素,因为序列是严格递增的,所以在

[网络流24题]最长递增子序列问题

题目大意:给定长度为n的序列a,求:1.最长递增子序列长度:2.最多选出几个不相交的最长递增子序列:3.最多选出几种在除了第1个和第n个以外的地方不相交的最长递增子序列.(n<=1000) 思路:先倒着DP,求出f[i]表示以a[i]开头的最长的递增子序列长度,然后建图,若f[i]=最长递增子序列长度则S向i连1,若f[i]=1则i向T连1,若i<j且a[i]<a[j]且f[i]=f[j]+1则i向j连1,为保证每个点只被流一次,拆成入点和出点,流量限制1,跑最大流即可解决第二问,点1和

最长单调递增子序列 POJ 3903 Stock Exchange .

题目传送门 : -------->点这里点这里<---------- 题目大意: 给出一串正整数,个数为N个.1<=N<=100000.求最长单调递增子序列长度. 样例输入: 6 5 2 1 4 5 3 3 1 1 1 4 4 3 2 1 样例输出: 3 1 1 =================================================================== 最长单调递增子序列问题的DP朴素算法复杂度为 O(n^2); 然而题目中的 N 最大有

最大子数组之和、最大子数组之积、最长递增子序列求法

昨天做爱奇艺笔试题,最后一道编程题是求整型数组最长递增子序列,由于时间关系,没有完全写出来,今天重新来做做这一系列题. <1> 最大子数组之和 首先从最简单的最大子数组之和求取.数组里有正数.负数.零.设包含第 i 个元素的子数组的和为 Sum,则Sum的值为 Sum(i) = Sum(i-1) + arrey[i]; 显然如果arrey[i]<=0,则Sum(i)<=Sum(i-1);则必须把Sum(i)=arrey[i];同时maxSum用来保存Sum最大值.时间复杂度为o(n

求数组中最长递增子序列

编程之美有一道关于数组中最长递增子序列,题目如下: 写一个时间复杂度尽可能低的程序,求一个一维数组(N个元素)中最长递增子序列的长度. 例如在序列1,-1,2,-3,4,-5,6,-7中,其最长的递增子序列的长度为4(如1,2,4,6),从该书给的例子我们可以知道的是其最长的递增子序列可以不连续的. 作者利用动态规划方法给了三种解法. 解法一: 根据无后效性的定义,各阶段按照一定的次序排列好之后,对于某个给定阶段的状态来说,它以前各阶段的状态无法直接影响它未来的决策,而只能间接地通过当前状态来影

递增子序列最大和

[问题描述] 给定长度为n的正整数序列a1,a2,…,an. 求一个递增的子序列,和最大. [输入] 第一行,n,表示给定序列的个数. 第二行,n个用空格隔开的正整数. [输出] 递增子序列的最大和. [数据范围限制] n<=1000,0<ai<=109. var a:array[1..100] of longint; f:array[1..100] of longint; n,i,j,ans:longint; function max(x,y:longint):longint; beg

HDURevenge of Segment Tree(第二长的递增子序列)

题目链接 题目大意:这题是求第二长的递增子序列. 解题思路:用n^2的算法来求LIS,但是这里还要记录一下最长的那个序列是否有多种组成方式,如果>= 2, 那么第二长的还是最长的LIS的长度,否则就是LIS - 1: 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1005; int l[maxn], c[maxn