传送门

思路:

对于一个串,如果我们知道了它翻转后最长的非递减子序列,那它去重之后一定是a1<a2<a3……<an 这种形式,ai只能取0~9

。所以我们可以求出原序列最大值, 最小值,构造一个pat匹配串,VL,VL+1,……VH,然后枚举翻转每一个区间(一共是C(10,2)个),和原串做最长公共子序列。在翻转区间的时候要多加上端点值,比如说, 122432445, pat串为12345,如果你直接翻转234,得到pat串为14325,这样匹配的话有两个2,两个4都不能匹配到,多以pat串应该为1243245;

其实求长度是好求的,但是区间就比较繁琐,可以开一个跟dp数组一样大的两个数组L,R,分别记录每个状态区间值,具体方法看一下代码注释比较好理解。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
char buf[N], pat[20], VL, VH;
int dp[N][15], cnt, L[N][15], R[N][15], ansl, ansr, ans;void init(){ans=-1;VL='9', VH='0';
}void _reverse(char l, char r, int& ll, int& rr){cnt=0;for(char k=VL; k<=l; k++)    pat[++cnt]=k;ll=cnt+1;for(char k=r; k>=l; k--)   pat[++cnt]=k;rr=cnt;for(char k=r; k<=VH; k++) pat[++cnt]=k;
}void solve(int l, int r){for(int i=0; i<=cnt; i++) dp[0][i]=0;for(int i=0; i<=n; i++) for(int j=0; j<=cnt; j++) L[i][j]=R[i][j]=-1;for(int i=1; i<=n; i++){for(int j=1; j<=cnt; j++){dp[i][j]=max(dp[i-1][j]+(buf[i]==pat[j]), dp[i][j-1]);/******************************************///找翻转区间if(dp[i-1][j]+(buf[i]==pat[j])>=dp[i][j-1]){//如果dp[i][j]由前一项转移而来L[i][j]=L[i-1][j]; R[i][j]=R[i-1][j];//它首先应该继承前一个状态的区间,这样能使L尽量的小if(buf[i]==pat[j]){if(l==j&&L[i][j]==-1) L[i][j]=i;//如果前一个状态没有L,则L可以赋值if(r==j) R[i][j]=i;//R只要能更新就一直更新,尽量的大}if(L[i][j]==-1&&L[i][j-1]!=-1){L[i][j]=L[i][j-1]; R[i][j]=R[i][j-1];//这是前后两个值相等的情况如果前面的赋值没有使得L获得一个区间值,可以从(i, j-1)获得}}else if(dp[i-1][j]+(buf[i]==pat[j])<dp[i][j-1]){//如果后者大,直接从后者获得L[i][j]=L[i][j-1]; R[i][j]=R[i][j-1];}/******************************************/}}if(ans<dp[n][cnt] && L[n][cnt]!=-1 && R[n][cnt]!=-1){ans=dp[n][cnt];ansl=L[n][cnt];ansr=R[n][cnt];}
}int main(){int T;scanf("%d", &T);while(T--){init();scanf("%d", &n);scanf("%s", buf+1);for(int i=1; i<=n; i++)VL=min(buf[i], VL), VH=max(buf[i], VH);if(VL==VH){printf("%d 1 1\n", n);continue;}for(char i=VL; i<=VH; i++){for(char j=i; j<=VH; j++){int ll, rr;_reverse(i, j, ll, rr);solve(ll, rr);}}printf("%d %d %d\n", ans, ansl, ansr);}return 0;
}/*
9
122265489
2
12
*/

HDU-6357Hills And Valleys(用最长可重复公共子序列求最长非递减子序列)相关推荐

  1. c语言连续非递减子序列,最长非递减子序列的应用

    Description 我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增.其中无论是修改前还是修改后,每个元素都必须是整数. 请输出最少需要修改多少个元素. In ...

  2. 动态规划(3):最长非递减子序列

    题目 在一个数字序列中,找到一个最长的子序列(可以不连续),使得这个子序列是不下降(非 递减)的. 样例 输入 8 1 2 3 -9 3 9 0 11 输出 6 题解 最优子结构(举例):以3结尾的最 ...

  3. 最长不重复子串python_寻找最长不重复子串

    寻找最长不重复子串 Longest Substring Without Repeating Characters Given a string, find the length of the long ...

  4. 【Effect CodeForces - 270D】Greenhouse (思维,最长非递减子序列(上升),对偶问题,考虑反面)

    题干: Emuskald is an avid horticulturist and owns the world's longest greenhouse - it is effectively i ...

  5. Manacher算法 - 求最长回文串的利器

    求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...

  6. 最短路:求最长最短路,求最短路的路径

    枚举删边跑Dijskra HDU - 1595 find the longest of the shortest #include <set> #include <map> # ...

  7. Dijkstra求最长路就是个坑!

    如HDU的4502,把题目抽象成一张图,把区间的头-1,这样就可以连接起来了. View Code #include <cstdio> #include <cstring> c ...

  8. LeetCode.3-最长无重复字符子串(Longest Substring Without Repeating Characters)

    这是悦乐书的第341次更新,第365篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第2题Longest Substring Without Repeating Cha ...

  9. 【动态规划】最长公共子序列与最长公共子串

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  10. 算法 求一个数组的最长递减子序列 C

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! //** ...

最新文章

  1. 寒武纪创始人兼CEO陈天石博士的公开信
  2. linux 用户管理(3)----查看用户登录时间以及命令历史
  3. WPF 将Bitmapsource转换到Emgu.cv.image
  4. JVM调优技巧与经验
  5. kafka offset保存在哪里_《Kafka成神之路》- 索引类型
  6. Linux记录-CPU指标介绍
  7. Python+Opencv实现无参数、全自动的Canny算法
  8. 多线程中的volatile和伪共享
  9. oracle报错:ORA-00054: 资源正忙,要求指定 NOWAIT
  10. 调用gserverdkey dll的飞鸽传书2012
  11. 安装fastdfs依赖包
  12. Tomcat 改BUG之 localhost:8080 404
  13. 【Flink】Flink 启动报错 DirectoryNotEmptyException Could not close resource
  14. Django搭建登录注册功能
  15. python-extend用法
  16. VS2010_x86_编译错误
  17. Ring Buffer 实现原理
  18. Nero 9官方正版下载(自带正版序列号)-最好的中文免费刻录软件
  19. “汇新杯”科技+社会公益专项赛介绍
  20. ios动态效果实现翻页_iOS动画--翻页动画

热门文章

  1. 毕业生签三方?报到证?档案户口?
  2. 微信限制收付款怎么解决_解决付款处理问题
  3. numpy 三角函数 sin()、cos()、tan() 反三角函数arcsin,arccos,arctan numpy.degrees()
  4. 00后小花张子枫亲力推荐 OPPO Reno6系列影像表现着实不俗
  5. java 解析uri_Uri详解之——Uri结构与代码提取
  6. 《问题笔记》【Office】Office安装失败问题及解决办法
  7. 操作系统实验——进程控制
  8. matlab 函数输出 向量,matlab中的函数返回向量
  9. 计算机硬盘从盘的设置,图文解说:电脑硬盘的主从盘设置方法_清风一笑
  10. 【OJ每日一练】1021 - 细菌个数