题意:长度为n的序列,有一次翻转区间的机会,问最长不减序列

题解:如果没有翻转区间的机会,有两个做法。

一是dp[i]表示以i结尾的最长序列 dp[i]=max(dp[i],dp[j]+1)  (j<=i)。

二是那个抽牌替换的解法。

这道题可以翻转但是值域很小,所以考虑最长子序列和值域的关系。

选择第一种解法改进。

显然不翻转的话是序列A与 序列B ={0123456789} 来匹配,B中的元素可以被匹配到多次。

现在要求翻转一次后的最长子序列,直接翻转A的复杂度是C(n,2)*n*10。

考虑有效翻转的意义,一定是将(只有)一个递减的序列变为递增。

这就相当于在被匹配的B序列中插入一个递减序列来被A匹配。

比如A是12345564678,直接匹配的对应的B'序列是12345(64)678,也就是B中多加了一个递减序列。

所以可以不翻转A,翻转B,这样复杂度就将为C(10,2)*n*20。

实现问题的话,可以在第二位数值域上多加10个来记录要添加的递减序列长度。

关于记录位置,因为只需考虑值域,所以只需开两个L[20],R[20]数组来记录以数字i结尾的(每个数分递减递增)左边和右边翻转区域即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+;
int dp[N][],n,T,len[],L[],R[];
int ans,l,r;
char s[N];
void solve(int ll,int rr){
int tar;
for(int i=;i<=n;++i) for(int j=;j<;++j) dp[i][j]=;
for(int i=;i<;++i) len[i]=;
for(int i=;i<;++i) L[i]=R[i]=;
for(int i=;i<=n;++i) {
tar=s[i]-'';
for(int j=tar;j>=;--j) {
if(dp[i][tar]<len[j]+) {
dp[i][tar]=len[j]+;
if(L[j]) L[tar]=L[j];else L[tar]=i;
if(R[j]) R[tar]=R[j];else R[tar]=i;
}
}
if(ll<=tar&&tar<=rr) {
for(int j=tar+;j<=+rr;++j) {
if(dp[i][tar+]<len[j]+) {
dp[i][tar+]=len[j]+;
if(!L[j]) L[tar+]=i;else L[tar+]=L[j];
R[tar+]=i;
}
}
for(int j=;j<=ll;++j) if(dp[i][tar+]<len[j]+){
dp[i][tar+]=len[j]+;
L[tar+]=R[tar+]=i;
}
}
if(tar>=rr) {
for(int j=+ll;j<=+rr;++j) {
if(dp[i][tar]<len[j]+) {
dp[i][tar]=len[j]+;
L[tar]=L[j],R[tar]=R[j];
}
}
}
if(dp[i][tar]>ans) ans=dp[i][tar],l=L[tar],r=R[tar];
if(ll<=tar&&tar<=rr&&ans<dp[i][tar+]) ans=dp[i][tar+],l=L[tar+],r=R[tar+];
for(int j=;j<;++j) len[j]=max(len[j],dp[i][j]);
}
}
int main(){
for(scanf("%d",&T);T--;){
scanf("%d",&n);
scanf("%s",s+);
ans=;
l=r=;
for(int i=;i<;++i) for(int j=i+;j<;++j) solve(i,j);
printf("%d %d %d\n",ans,l,r);
}
}

最新文章

  1. java中的字符串相关知识整理
  2. 在 Android Studio中恢复已经被移除的Module
  3. Mina、Netty、Twisted一起学(一):实现简单的TCP服务器
  4. jQuery中attr() 和 prop()【转】
  5. Raphael 目标点沿路径不断移动
  6. python绝技 — 扫描蓝牙RFCOMM信道
  7. HDU 5821 Ball
  8. NodeJS之异常处理
  9. day4(分支结构,循环结构,for循环,九九乘法表)
  10. 金融量化分析【day110】:Pandas-DataFrame索引和切片
  11. MySQL-mysql 8.0.12安装教程
  12. 【Eclipse】Eclipse中打开cmd窗口和terminal窗口
  13. 关于PHP程序员技术职业生涯规划 转自 韩天锋
  14. springboot(整合事务和分布式事务)
  15. Linux 解压 压缩文件
  16. leetCode(28):Contains Duplicate II
  17. HDOJ 4010 Query on The Trees LCT
  18. MySQL的表分区详解 - 查看分区数据量,查看全库数据量----转http://blog.csdn.net/xj626852095/article/details/51245844
  19. 第十章 Secret &amp; Configmap(下)
  20. BZOJ 2225 [Spoj 2371]Another Longest Increasing(CDQ分治)

热门文章

  1. Scala教程之:可变和不变集合
  2. python的sqlalchemy框架
  3. 业务SQL那些事--慎用LIMIT
  4. MySQL重新初始化安装数据库
  5. 编写C#程序的IDE
  6. 老师,你确定Java注释不会被执行吗?
  7. 初识CoAP协议
  8. 【学习笔记】Shell-1 变量:命名规范、变量赋值/取值/取消、局部变量/全局变量、预设环境变量
  9. 【Hadoop离线基础总结】oozie的安装部署与使用
  10. apply call bind的用法与实现