zoukankan      html  css  js  c++  java
  • 【HDU5748】Bellovin

    Description

    Peter has a sequence  and he define a function on the sequence -- , where  is the length of the longest increasing subsequence ending with 

    Peter would like to find another sequence  in such a manner that  equals to . Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one. 

    The sequence  is lexicographically smaller than sequence , if there is such number  from  to , that  for  and .

    Input

    There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case: 

    The first contains an integer   -- the length of the sequence. The second line contains  integers  .

    Output

    For each test case, output  integers   denoting the lexicographically smallest sequence. 

    Sample Input

    3
    1
    10
    5
    5 4 3 2 1
    3
    1 3 5

    Sample Output

    1
    1 1 1 1 1
    1 2 3

    【题解】

    这题就是要求最长不下降子序列。

    不同的是,它不是要求你求出来最长不下降子序列的各个值具体是什么。

    它要求的是以ai结尾的最长不下降子序列的长度f[i].

    但是这题的坑点在于。它不让你用那么方便的n^2算法。要用nlogn算法才行。所以就去找咯。

    原来的f[i]要改一下意思了。变成长度为i的最长上升(严格上升)序列的最后一个元素的最小值是啥。

    一开始len = 1;f[1] = a1;

    然后for i = 2->n 

    if (a[i] > f[len]) //这个很好理解吧?就是如果大于长度为len的最后一个元素.则最长XX的长度递增。

    {
    len++; 

    f[len] = a[i]; //然后把新的元素接上去就好

    直接输出len.表示以a[i]结尾的最长不下降子序列的长度为len;

    }

    else

    {

    找到一个k

    f[k-1]<a[i]<=f[k];

    因为a[i] <= f[k]且f[k-1]<a[i] 则说明其可以代替f[k]成为一个更小的f[k]'。

    那么就让f[k] = a[i]就好;

    这个k可以用二分查找找到(鬼才想去写这个二分查找。跟屎一样难写!)

    所以我们用STL解决(就是algorithm这个头文件里的东西。)

    它叫。我看下我能不能默下来lower__count??

    我看下。

    哦,错了

    是lower_bound(f+1,f+1+len,a[i])-f;

    你没看错最后面减去了一个数组

    然后前面就是类似sort(a+1,a+1+len);

    表示从1..len找到这样的k;

    然后f[k] = a[i];

    然后输出k.表示以a[i]为结尾的最长不下降子序列的长度为k;

    }

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    int t, n, a[100001], f[100001], last = 1, ans[100001];
    
    int main()
    {
    	scanf("%d", &t);
    	for (int mm = 1; mm <= t; mm++)
    	{
    		scanf("%d", &n);
    		for (int i = 1; i <= n; i++)//读入数据
    			scanf("%d", &a[i]);
    		f[1] = a[1];//最长不下降子序列长度为1的最小结尾元素一开始就是a[1]
    		ans[1] = 1;//没用的。。别管
    		printf("1");//表示以a1为结尾的最长不下降子序列的长度为1
    		last = 1;
    		for (int i = 2; i <= n; i++)
    		{
    			if (f[last] < a[i])//因为更新了最长不下降子序列的长度
    			{
    				last++;
    				printf(" %d", last);//所以以其结尾的元素的长度为last;
    				f[last] = a[i];
    			}
    			else
    			{
    				int pos = lower_bound(f + 1, f + 1 + last, a[i]) - f;//找到合适的K值
    				f[pos] = a[i];//放在这个位置
    				printf(" %d", pos);//输出它的长度、即以a[i]为结尾的最长不下降子序列的长度。
    			}
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    


  • 相关阅读:
    关于Linux静态库和动态库的分析
    某个表格不知道被哪个Session 锁住了,及如何解锁
    如何降低索引的clustering_factor
    Oracle Logminer 查找日志信息
    使用“alter index ××× monitoring usage;”语句监控索引使用与否(转载secooler) 转
    Oracle提高查询效率的解析
    数据库flash_recovery_area满导致数据库启动报错ORA03113错误
    ora错误代码汇总
    Oracle BBED 工具介绍
    oracle BBED 直接修改数据库block块
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632288.html
Copyright © 2011-2022 走看看