【神奇的dp】poj 6357 Hills And Valleys

编程入门 行业动态 更新时间:2024-10-09 16:31:13

【<a href=https://www.elefans.com/category/jswz/34/1764804.html style=神奇的dp】poj 6357 Hills And Valleys"/>

【神奇的dp】poj 6357 Hills And Valleys

【神奇的dp】poj 6357 Hills And Valleys

【题目链接】


题目

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.


题目大意和解题思路

T组数据,每组给一个长为n[1,1e5]的串,串里是[0,9],问翻转其中某一段后能达到的最长不减子序列有多长,输出长度和翻转串的左右下标。

比赛的时候没多想,只看出肯定要转成几个0+几个1+几个2+……+几个9,区间可以转化为看它值域为[0,9][1,3]之类的递减序列有多长,复杂度肯定是过不了的。。。

看直播讲题的时候一直在想大佬的按值域枚举区间是什么玩意儿,还有枚举完和原串匹配,其实就是把所有连续相同的点全都看成一个以后,最后的递增子序列肯定是0123456789的子序列,这就是所谓的值域,找递增子序列的过程就相当于用这个串和原串匹配。
这个枚举就是比如翻转值域[2,5],它对应的值域是012 5432 56789,用原串和这个串匹配得到对应的最长序列,一共45种,比较一下就可以了。找翻转区间的过程类似找最长公共子序列的路径,就是路径上纵坐标对应翻转了的值域的那一部分。


AC代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e5+7;int a[maxn],b[maxn];
char s[maxn];
int dp[maxn][23];
int dir[maxn][23];///0代表来自i-1,1代表来自j-1,-1代表来自i-1并且+了1
int main()
{int T,m,n,i,j,x,y,cnt,maxx,l,r,ans;scanf("%d",&T);while(T--){scanf("%d",&n);scanf("%s",s+1);for(i=1;i<=n;i++) a[i]=s[i]-'0';ans=0;for(l=0;l<=9;l++){for(r=l+1;r<=9;r++){cnt=0;for(i=0;i<=l;i++) b[cnt++]=i;for(i=r;i>=l;i--) b[cnt++]=i;for(i=r;i<=9;i++) b[cnt++]=i;for(i=1;i<=n;i++){for(j=0;j<cnt;j++){dp[i][j]=dp[i-1][j];dir[i][j]=0;if(a[i]==b[j]){dp[i][j]++;dir[i][j]=-1;}if(dp[i][j]<dp[i][j-1]){dir[i][j]=1;dp[i][j]=max(dp[i][j],dp[i][j-1]);}}}if(ans<dp[n][cnt-1]){ans=dp[n][cnt-1];i=n,j=cnt-1;x=y=1;cnt=1;bool flag=1;while(i>=1&&j>0){if(j>=l+1&&dir[i][j]==-1) x=i;if(j<=r+1&&flag&&dir[i][j]==-1) flag=0,y=i;if(dir[i][j]==1) j--;else i--;}}}}printf("%d %d %d\n",ans,x,y);}return 0;
}

更多推荐

【神奇的dp】poj 6357 Hills And Valleys

本文发布于:2024-02-06 08:13:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1747459.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:神奇   dp   poj   Valleys   Hills

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!