0
点赞
收藏
分享

微信扫一扫

hdu6357(DP姿势 LIS->LCS)


这个题想了好久。。其实已经想到枚举x和y了然后就不造怎么dp。。

这个姿势比较特殊,得学一下。。

枚举完x和y之后先把简化的序列b构造出来,即1 2 3 ..x y y-1 y-2 ... x+1 x y y+1 ... n这样。。

然后以类似lcs的方式去匹配b,当然要算重复的点。。

具体来说就是设d[i][j]为匹配到原序列i位置和b序列中的j位置的a的最长序列

那么d[i][j]=max{d[i-1][k]}+a[i]==b[j]   k=1..j

由于j很小啊只有30,直接枚举暴力匹配,复杂度是O(

hdu6357(DP姿势 LIS->LCS)_#include

)

暴力dp确实得多练练。。不然老是想太多。。

 

 

/**
*         ┏┓    ┏┓
*         ┏┛┗━━━━━━━┛┗━━━┓
*         ┃       ┃  
*         ┃   ━    ┃
*         ┃ >   < ┃
*         ┃       ┃
*         ┃... ⌒ ...  ┃
*         ┃ ┃
*         ┗━┓ ┏━┛
*          ┃ ┃ Code is far away from bug with the animal protecting          
*          ┃ ┃ 神兽保佑,代码无bug
*          ┃ ┃           
*          ┃ ┃       
*          ┃ ┃
*          ┃ ┃           
*          ┃ ┗━━━┓
*          ┃ ┣┓
*          ┃ ┏┛
*          ┗┓┓┏━━━━━━━━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1LL<<(x))
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 100005
#define nm 100005
#define N 40005
#define M(x,y) x=max(x,y)
const double pi=acos(-1);
const ll inf=1e9+7;
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}





int n,tot,d[NM][31],b[31],a[NM],p[NM][31],ans,ansl,ansr;

int main(){
//freopen("data.in","r",stdin);
int _=read();while(_--){
ans=0;
n=read();inc(i,1,n)scanf("%1d",a+i);
inc(k,0,9)inc(v,k,9){
tot=0;
inc(i,0,k)b[++tot]=i;
dec(i,v,k)b[++tot]=i;
inc(i,v,9)b[++tot]=i;
inc(i,1,n){
int t=0;
inc(j,1,tot){
if(d[i-1][j]>d[i-1][t])t=j;
p[i][j]=t;d[i][j]=d[i-1][t]+(a[i]==b[j]);
}
}
dec(j,tot,1)if(d[n][j]>ans){
ans=d[n][j];int t=j,l=0,r=0;
dec(i,n,0){
if(!l&&t<=k+1)l=i+1;
if(!r&&t<=v+2)r=i;
t=p[i][t];
}
if(r==0)r=l;
ansl=l;ansr=r;
}
}
printf("%d %d %d\n",ans,ansl,ansr);
}
return 0;
}

 

 

 

Hills And Valleys

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 758    Accepted Submission(s): 229
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≤lrn) 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<⋯<xmn 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:  ​​6361​​​ ​​6360​​​ ​​6359​​​ ​​6358​​​ ​​6357​​ 

 

​​Statistic​​​ | ​​Submit​​​ | ​​Discuss​​​ | ​​Note​​

举报

相关推荐

0 条评论