神奇的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
发布评论