AGC007 F Shik and Copying String
阿新 • • 發佈:2018-12-11
題意
從S串變成T串 每個字串中的字元要麼是上個字串的對應位置的字元,要麼是這個字串的左邊一個的字元。 問要進行幾次轉化才能從S變成T
題解
可以發現,其實就是如圖所示的折線式的轉移(注意不要被誤導了,這是樣例,但不是最優的轉移方案) 或者說再看這一個圖 由於c的折線和左邊那個a有衝突,所以a只能延緩它右拐的時間
那我們具體怎麼實現呢 這個折線只能拐右和向下 首先,我們只需要考慮連續的字元的最左端 對於T串上一個位置i 我們先求出當前還未被訪問的,<=i的,S[p]==T[i]的最大的p 我們從大到小列舉i,然後從p到i,貪心地想,我們始終儘可能往右走 所以對於一條直線,它所對應的深度就是拐點數量+1 如何維護拐點呢 我們把之前的p壓進佇列 對於每個拐點來說,他的橫向長度應該是1 是這樣嗎?存疑
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+5;
typedef long long ll;
char S[N],T[N];
int n;
int s,t,q[N];
int main()
{
scanf("%d",&n);
scanf("%s",S+1);
scanf ("%s",T+1);
if(strcmp(S+1,T+1)==0){
puts("0");
return 0;
}
s=1,t=0;
int p=n;
int ans=0;
for(int i=n;i>=1;i--){
if(T[i]==T[i-1])
continue;
p=min(p,i);
while(p&&T[i]!=S[p])
p--;
if(!p){
puts ("-1");
return 0;
}
while(s<=t&&q[s]-(t-s+1)+1>i)
s++;
q[++t]=p;
if(i!=p)
ans=max(ans,t-s+1);
}
printf("%d\n",ans+1);
}