Hills And Valleys
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 894 Accepted Submission(s): 279
Special Judge
Problem Description
Tauren has an integer sequence A of length n (1-based). He wants you to invert an interval [l,r] (1≤l≤r≤n) of A (i.e. replace Al,Al+1,⋯,Ar with Ar,Ar−1,⋯,Al) to maximize the length of the longest non-decreasing subsequence of A. Find that maximal length and any inverting way to accomplish that mission.
A non-decreasing subsequence of A with length m could be represented as Ax1,Ax2,⋯,Axm with 1≤x1<x2<⋯<xm≤n and Ax1≤Ax2≤⋯≤Axm.
Input
The first line contains one integer T, indicating the number of test cases.
The following lines describe all the test cases. For each test case:
The first line contains one integer n.
The second line contains n integers A1,A2,⋯,An without any space.
1≤T≤100, 1≤n≤105, 0≤Ai≤9 (i=1,2,⋯,n).
It is guaranteed that the sum of n in all test cases does not exceed 2⋅105.
Output
For each test case, print three space-separated integers m,l and r in one line, where m indicates the maximal length and [l,r] indicates the relevant interval to invert.
Sample Input
2 9 864852302 9 203258468
Sample Output
5 1 8 6 1 2
Hint
In the first example, 864852302 after inverting [1, 8] is 032584682, one of the longest non-decreasing subsequences of which is 03588. In the second example, 203258468 after inverting [1, 2] is 023258468, one of the longest non-decreasing subsequences of which is 023588.
Source
2018 Multi-University Training Contest 5
Recommend
chendu | We have carefully selected several similar problems for you: 6373 6372 6371 6370 6369
代码:
#include<bits/stdc++.h>
using namespace std;
const int N =1e5+5;
int dp[N][15];
int b[12];
char s[N];
int a[N];
int maxx,minn;
int lt[N][15],rt[N][15];
int ansl,ansr;
int bl,br;
int n;
void jiaohuan(int l,int r)
{
int tot=0;
for(int i=0;i<=l;i++) b[++tot]=i;
for(int i=r;i>=l;i--) b[++tot]=i;
for(int i=r;i<=9;i++) b[++tot]=i;
}
int getdp()
{
for(int i=0;i<=n;i++){
for(int j=0;j<=12;j++){
dp[i][j]=0; lt[i][j]=rt[i][j]=0;
}
}
for(int i = 1;i<= n;i++)
{
for(int j = 1;j<=12;j++)
{
dp[i][j] = dp[i-1][j];
rt[i][j] = rt[i-1][j];
lt[i][j] = lt[i-1][j];
if(a[i] == b[j])
{
dp[i][j]++;
if(bl == j&<[i][j] == 0)
lt[i][j] = i;
if(br == j)
rt[i][j] = i;
}
if(dp[i][j-1]> dp[i][j])
{
dp[i][j] = dp[i][j-1];
rt[i][j] = rt[i][j-1];
lt[i][j] = lt[i][j-1];
}
}
}
/*
for(int i=1;i<=n;i++){
for(int j=1;j<=12;j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
cout<<"**** "<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=12;j++){
cout<<lt[i][j]<<" ";
}
cout<<endl;
}
cout<<"**** "<<endl;
for(int i=1;i<=n;i++){
for(int j=1;j<=12;j++){
cout<<rt[i][j]<<" ";
}
cout<<endl;
}
cout<<"**** "<<endl;
*/
return dp[n][12];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
scanf("%s",s+1);
maxx=-1; minn=15;
for(int i=1;i<=n;i++){
a[i]=s[i]-'0';
maxx=max(a[i],maxx);
minn=min(a[i],minn);
}
for(int i=0;i<=9;i++) b[i+1]=i;
int ans=getdp();
ansl=1; ansr=1;
for(int i=minn;i<=maxx;i++){
for(int j=i+1;j<=maxx;j++){
jiaohuan(i,j);
bl=i+2; br=j+2; /// 记录翻转区间在b数组中的位置
int tmp=getdp();
if(tmp>ans){
ans=tmp;
if(lt[n][12]!=0&&rt[n][12]!=0){
ansl=lt[n][12];
ansr=rt[n][12];
}
}
}
}
printf("%d %d %d\n",ans,ansl,ansr);
}
return 0;
}
/*
1
12
123335435557
*/