当前位置: 首页 > news >正文

UVa1471 Defense Lines(LIS变形)

题目链接
在这里插入图片描述
1.题目描述:给定一个长度为n的序列,现在可以删除一段任意长度的子序列,使得删除后剩下的序列中有长度最大的连续递增子序列

2.这个题目很新颖,刚开始看裸写了一个LIS,一看样例过了兴致勃勃的交了上去,结果WA了。仔细一看,这里只能删一段序列,并不是任意跳跃式的选择,而且最后的答案是最长的连续递增子序列。如果单纯地求连续递增子序列还好说,现在可有点麻烦

3.顺着刘老师的思路看下去,预处理以i下标开头的最长连续递增子序列长度,以j结尾的最长连续递增子序列长度,那么就是枚举i,快速找一个j<i使得a[j] < a[i]而且g(j)+f(i)尽量大。下面讲了使用set的思路,看了看,好长好麻烦,又要插入删除和二分查找,真的不想写。又看到下一页最下面写着:可以用LIS的nlog(n)算法避开set,也就是第二种方法

4.去网上看了看,果不其然,我是看这篇博客学习的。首先整体思路不变,仍然是使用f(i)记录以i结尾的的最长递增子序列的长度,g(i)记录以i开头的最长递增子序列的长度,和普通的LIS类似,利用一个数组d[i]记录长度为 i 的连续递增序列的最后一个元素的最小值,显然该序列是单调递增的,所以可以通过二分查找直接得到f[j]的值,进而得到一个可行的长度ans, 然后更新数组d即可,更新的方法是如果以a[i]小于数组d中记录的与a[i]长度相同的序列的最后一个元素的值,那么把这个值改为a[i], 即 d[f[i]] = min(a[i], d[f[i]]); 最终ans的最大值即为答案

5.其他的都懂,就是为什么d[i]会保证单调性这里真的头看破都想不通,属实无奈便模拟了第一个样例:
9
5 3 4 9 2 8 6 7 1
在这里插入图片描述
6.最后简单证明一下为什么d数组是单调的(初始化均为INF):
设p,q为两个连续的长度,他们对应数组下标分别为i,j,很明显q=p+1且肯定有a[i]<a[j]。假设当前正在判断p、q,如果之前长度p的d[p]没有被更新,那么显而易见;如果之前有p` =p:
①若之前有d[p`]<a[i],那么d[p`]不更新,一定有d[p`]<a[j]
②若之前有d[p`]>a[i],那么d[p`]更新为a[i],后面一定有d[q]由INF更新为a[j],那么d[p]<a[j]=d[q]
证毕

#include <iostream>
#include <set>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x7fffffff
const int maxn=2e5+10;

int a[maxn],f[maxn],g[maxn],d[maxn];

int main(){
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++){
            if(a[i]>a[i-1])
                f[i]=f[i-1]+1;
            else f[i]=1;
        }
        g[n]=1;
        for(int i=n-1;i>=1;i--){
            if(a[i]<a[i+1])
                g[i]=g[i+1]+1;
            else g[i]=1;
        }
        for(int i=0;i<=n;i++) d[i]=INF;
        int ans=0;
        for(int i=1;i<=n;i++){
            int len=(lower_bound(d+1,d+1+i,a[i])-(d+1))+g[i];
            ans=max(ans,len);
            d[f[i]]=min(a[i],d[f[i]]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

相关文章:

  • 计蒜客43467 Canyon Crossing(二分答案+多队列bfs)
  • 三句代码调整进程优先级
  • UVa714 Copying Books(二分答案+贪心)
  • 《程序员羊皮卷》成为电子工业出版社本周重点推荐图书
  • UVa12627 Erratic Expansion(递归/找规律)
  • 《金牌网管师》——10年的沉淀,18年的积累
  • 2020 CodeJam Round 1A
  • 如何更换Android模拟器界面
  • 2019 ICPC Latin American Regional Contests 计蒜客重现
  • youtube weburl后缀
  • UVa12174 Shuffle(滑动窗口)
  • Android开发指南-工具-画九宫格
  • UVa1608 Non-boring sequences(尺取+分治)
  • 通过枚举窗口获得窗口句柄名字并重命名窗口
  • “Shopee杯” e起来编程暨WHU2020校赛热身赛
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 2017 前端面试准备 - 收藏集 - 掘金
  • Android开源项目规范总结
  • co.js - 让异步代码同步化
  • IP路由与转发
  • JavaScript的使用你知道几种?(上)
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • React+TypeScript入门
  • windows-nginx-https-本地配置
  • Yii源码解读-服务定位器(Service Locator)
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 搞机器学习要哪些技能
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 关于字符编码你应该知道的事情
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 如何用vue打造一个移动端音乐播放器
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • MyCAT水平分库
  • 选择阿里云数据库HBase版十大理由
  • ​2021半年盘点,不想你错过的重磅新书
  • #Linux(权限管理)
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • (9)目标检测_SSD的原理
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (ZT)薛涌:谈贫说富
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (规划)24届春招和25届暑假实习路线准备规划
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (数据结构)顺序表的定义
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)Linq学习笔记
  • .cfg\.dat\.mak(持续补充)
  • .chm格式文件如何阅读
  • .NET CLR Hosting 简介
  • .NET gRPC 和RESTful简单对比
  • .NET 命令行参数包含应用程序路径吗?
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖