1275: God's ladder [DP]

时间限制: 1 Sec 内存限制: 128 MB  Special Judge

题目描述

天明来到神之宫殿,在他眼前出现了若干个石柱,每个石柱上有1枚金币,天明可以任意选择一个石柱开始,然后向前方的石柱瞬移,而且他所瞬移到的石柱的高度必须要大于现在所在石柱的高度。

求天明所能获得的最大金币数以及任意一种可以获得这么多金币的路线(每个石柱的高度)。

输入

第一行一个数n,表示石柱的个数。

然后2~n+1行,每行一个石柱的高度h[i],分别是1,2,,n石柱的高度。

2<n<200100;1<= h[i] < 15000000;

输出

第一行为一个数m,表示最大金币数。

2~m+1行,每行一个数,分别是每次所瞬移到的石柱的高度。

样例输入

7

3

1

2

5

9

6

7

样例输出

5

1

2

5

6

7

代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define  inf  0x3f3f3f3f
int dp[200220],list[200220],a[200220];//dp[i]保存lis为i时最小的元素,list保存每个元素的lis;
int main()
{
    int n,i,j,k,p;
    while (cin>>n){p=0;
    memset(dp,inf,sizeof(dp));
        for(i=0;i<n;i++){
            scanf("%d",&a[i]);
    *lower_bound(dp,dp+n,a[i])=a[i];          //记录更新长度对应的最大潜力元素时,顺便记录下该元素对应的LIS长度
    list[p++]=lower_bound(dp,dp+n,a[i])-dp+1;
        }
        k=lower_bound(dp,dp+n,inf)-dp;     //总的LIS
        cout<<k<<endl;
        int m=k;
        for(i=n-1;i>=0;i--){                          //从右至左扫描一遍直至找全LIS长度
            if(k==list[i])
            dp[k--]=a[i];
            if(!k) break;
    }
    for(i=1;i<=m;i++)printf("%d\n",dp[i]);
    }
    return 0;
}
 
 
更快的解法,减小二分搜索的次数:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define  inf  0x3f3f3f3f
int dp[200220],list[200220],a[200220];
int main()
{
    int n,i,j,k,p;
    while (cin>>n){p=0;k=0;
    memset(dp,inf,sizeof(dp));
        for(i=0;i<n;i++){
            scanf("%d",&a[i]);
 if(a[i]>dp[k])  dp[++k]=a[i];      // 设置k为当前最长lis值
   else*lower_bound(dp,dp+k,a[i])=a[i];  
     list[p++]=lower_bound(dp,dp+k,a[i])-dp+1;
        }
    //    k=lower_bound(dp,dp+n,inf)-dp;
    k=k+1;
        printf("%d\n",k);
        int m=k;
        for(i=n-1;i>=0;i--){
            if(k==list[i])
            dp[k--]=a[i];
            if(!k) break;
    }
    for(i=1;i<=m;i++)printf("%d\n",dp[i]);
    }
    return 0;
}
从右至左扫描的必要性:
由于是求单调上升子序列,所以最大值定在右侧。
又具有相同lis的不同元素中,潜力最大的也在右侧。
即假设一个元素的lis为n(n>2),则在这个元素之前定有lis为(n-1)且小于此元素的原宿存在。

二分求LIS并打印结果的更多相关文章

  1. hdu5256 二分求LIS+思维

    解题的思路很巧,为了让每个数之间都留出对应的上升空间,使a[i]=a[i]-i,然后再求LIS 另外二分求LIS是比较快的 #include<bits/stdc++.h> #define ...

  2. hdu 1025LIS思路同1257 二分求LIS

    题目: Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  3. HDU 5773 The All-purpose Zero(O(nlgn)求LIS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5773 题意: 求LIS,其中的0可以看做任何数. 思路: 因为0可以看做任何数,所以我们可以先不管0,先求一遍L ...

  4. nlogn求LIS(树状数组)

    之前一直是用二分 但是因为比较难理解,写的时候也容易忘记怎么写. 今天比赛讲评的时候讲了一种用树状数组求LIS的方法 (1)好理解,自然也好写(但代码量比二分的大) (2)扩展性强.这个解法顺带求出以 ...

  5. UVA 10635 Prince and Princess—— 求LCS(最长公共子序列)转换成 求LIS(最长递增子序列)

    题目大意:有n*n个方格,王子有一条走法,依次经过m个格子,公主有一种走法,依次经过n个格子(不会重复走),问他们删去一些步数后,重叠步数的最大值. 显然是一个LCS,我一看到就高高兴兴的打了个板子上 ...

  6. 【模板】O(nlongn)求LIS

    合理运用单调性降低复杂度 平常用的都是O(n^2)的dp求LIS(最长不下降子序列)这里介绍O(nlogn)的算法 分析 对于可能出现的x<y<i且A[y]<A[x]<A[i] ...

  7. Codeforces 486E LIS of Sequence --树状数组求LIS

    题意: 一个序列可能有多个最长子序列,现在问每个元素是以下三个种类的哪一类: 1.不属于任何一个最长子序列 2.属于其中某些但不是全部最长子序列 3.属于全部最长子序列 解法: 我们先求出dp1[i] ...

  8. 九度OJ 1085 求root(N, k) -- 二分求幂及快速幂取模

    题目地址:http://ac.jobdu.com/problem.php?pid=1085 题目描述: N<k时,root(N,k) = N,否则,root(N,k) = root(N',k). ...

  9. 二分求幂/快速幂取模运算——root(N,k)

    二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...

随机推荐

  1. web前端----JavaScript(JS)简单介绍

    JavaScript(JS) 一.JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEa ...

  2. ESOURCE_LOCKED - cannot obtain exclusive access to locked queue '2484_0_00163'

    早上一运维同事说,一个报盘程序启动的时候报了"ESOURCE_LOCKED - cannot obtain exclusive access to locked queue '2484_0_ ...

  3. mysql jdbc性能优化之mybatis/callablestatement调用存储过程mysql jdbc产生不必要的元数据查询(已解决,cpu负载减少20%)

    INFO | jvm 1 | 2016/08/25 15:17:01 | 16-08-25 15:17:01 DEBUG pool-1-thread-371dao.ITaskDao.callProce ...

  4. .net Core 中将原MVC中的 MvcHtmlString转换

    public static IHtmlContent CustomLabelFor<TModel, TProperty>(this IHtmlHelper helper, Expressi ...

  5. 20145334赵文豪 WEB基础实践

    实验问题回答 1.什么是表单 表单在网页中主要负责数据采集功能 一个表单有三个基本组成部分: 表单标签 表单域:包含了文本框.密码框.隐藏域.多行文本框.复选框.单选框.下拉选择框和文件上传框等 表单 ...

  6. c++类定义代码的分离

    类文件 实际工程中,对一个类的说明.架构.描述方法是:    往往分成头文件和实现的源文件,来实现代码的分离 然后,源文件中包含类的头文件... 头文件的包含问题: 类对应的实现文件cpp.main主 ...

  7. HDU 1285 确定比赛名次(拓扑排序)题解

    Problem Description 有N个比赛队(1<=N<=500),编号依次为1,2,3,....,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委 ...

  8. echart折线图,柱状图,饼图设置颜色

    转载: 之前在做报表的时候用过echart 用完也就完了,而这次在用的时候已经忘了,所以这里简单记录一下,好记性不如烂笔头!!! 1.折线图修改颜色: xAxis: { type: 'category ...

  9. js函数事件对象

    每个函数都有4个默认对象 arguments 保存着实际传入的参数,集合列表 return 有两个功能,打断函数和返回函数值 this 谁调用的函数,this就是谁 event 事件对象 事件 box ...

  10. Windows 10 无法调节亮度的解决办法

    我的笔记本在更新完14393后开始的一段时间内是可以正常调节亮度的,但是后来就莫名奇妙地不能调节亮度了,而且电源选项里的亮度调节滚动条也不见了.网上查了很多方法,诸如修改注册表.更新驱动之类的都试过, ...