bzoj4032 [HEOI2015] 최단 비공식 하위 문자열 (문자열 dp+SAM)
분석: 문자열 dp사합일은 신의 한 문제입니다. 처음에는 첫 번째 질문만 할 줄 알았는데 자신의 방법이 믿음직하지 않다는 것을 발견했습니다.
First.A 문자열≠ B 문자열
실제로 두 열의 가장 긴 공통 서브열 f[i][j]f[i][j]는 A 서열 ii위가 B 서열 jj위와 일치한다는 것을 나타낸다. 가장 긴 공통 서브열 f[i][j]=f[i]=f[i-1][j][j-1]+1(A[i]=B[j])f[i][j]=f[i]=f[i-1][j][j][j]+1(A[i]=B[j])의 답은 모든 가장 긴 공통 서브열 중 가장 작은 값이다.
여기서 주의해야 할 점은 다음과 같습니다.
if (a!=i) ans=min(ans,a+1);
기록된 최대 공통 문자열 길이
왜 a!=ia!=i 때 답안을 업데이트할 수 있을까요?
a==ia==i 때문에 AA 서열 1:i 1:i 비트가 모두 일치한다는 것을 의미한다. 그러면 얻은 답안은 a+1a+1이 의미가 없을 수도 있다(A와 B 서열이 완전히 같을 수도 있고 정답은 -1일 수도 있다)
Second.A 문자열 ≠ B 시퀀스
욕심은 일괄서열 A의 일치점, 욕심의 일치 B서열도 우리는 dp로 f[i][j][j][i][j][j]]를 완성할 수 있다. 매거서열 A의 일치점, 욕심의 일치 B서열은 우리가 dp로 f[i][j][i][j][j]=f[i: [i: 1] [j-1] [j]+1(A[i]=1] [[i]=[[[i]=B[[[j]] [i] [i] [j][[i] [[[[j]] [[j]] [[j][[[[j]]]][[[[[[j]]]]][[[[[[j]]]][[[[[j]]]]]][[[j]]][(A[i]!=B[j]) f[i][j]=f[i][j-3-1](A[i]!=B[j])
왜 같지 않을 때 이렇게 옮겨요?우리가 매거한ii의 A의 하위 문자열은 반드시 연속적이기 때문에ii가 반드시 일치해야 하기 때문에ii는 움직일 수 없습니다
또는 참고:
if (a!=i) ans=min(ans,a+1);
Third.A 하위 시퀀스≠ B 하위 문자열
B열로 SAMSAM 디자인 상태 만들기: l[i]l[i]는 SAMSAM의 결점ii로 A 서열을 매칭하면 얻을 수 있는 가장 짧은 길이를 나타낸다. 우리는 A의 매개ii와 SAMSAMSAM의 매개점 jj가ch[j][i][j]이 매칭하면 매칭할 수 있는 가장 짧은 길이를 나타낸다. 따라서 l[ch[j][i]]]]]=min(l[j]+1)l[ch[j][j][i]]][l[j]]][i]]]][lj][i]]][lj][i]]+1](lj]+1)
Fourth.A 서브시퀀스≠ B 서브시퀀스
세 번째 질문과는 차이가 많지 않지만 둘 다 하위 서열이기 때문에 우리는 하나의 수조 ccc[i][j]c[i][j][j]를 미리 처리해야 한다. B 서열에서 ii위 이전 문자 jj의 최근 위치를 표시한다.
우리는 또한 욕심 많은 생각을 이용하여 l[i]l[i]는 문자열 B의 ii위에 일치하는 가장 짧은 길이의 매거 A의 각 ii, 거꾸로 매거 B의 각 jj(우리가 cc수조를 구성하는 의미에 주의)를 나타낸다. 만약에 c[j][A[i]]]c[j][A[A]]]]라는 결점이 있다면 j가 이전에 A[i]A[i]와 일치할 수 있는 위치가 있었다는 것을 의미한다. 따라서 l[c[j][A[i][i]]]]][l[j]+1][ji][jj][j][jj][j][j]][jj]]][ji][j][j]]]][jj][j][j]]]][jj]][jj]]
tip
하늘만큼 큰 구덩이:
if (a!=i) ans=min(ans,a+1);
다라오들이 무릎을 꿇고 힘을 내는 걸 보고 한 발씩 했어요.#include
#include
#include
using namespace std;
const int INF=1e9;
const int N=4005;
int dis[N],ch[N][26],fa[N],last=1,root=1,sz=1,len;
int f[2003][2003],l[N],l1,l2,c[N][26],mp[26];
char s[N],ss[N];
void insert(int x)
{
int now=++sz,pre=last;
last=now;
dis[now]=dis[pre]+1;
for (;pre&&!ch[pre][x];pre=fa[pre]) ch[pre][x]=now;
if (!pre) fa[now]=root;
else
{
int q=ch[pre][x];
if (dis[q]==dis[pre]+1) fa[now]=q;
else
{
int nows=++sz;
dis[nows]=dis[pre]+1;
memcpy(ch[nows],ch[q],sizeof(ch[q]));
fa[nows]=fa[q]; fa[q]=fa[now]=nows;
for (;pre&&ch[pre][x]==q;pre=fa[pre]) ch[pre][x]=nows;
}
}
}
void solve1()
{
memset(f,0,sizeof(f));
int ans=INF;
for (int i=1;i<=l1;i++)
{
int a=0;
for (int j=1;j<=l2;j++)
{
if (s[i]==ss[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1);
a=max(a,f[i][j]);
}
if (a!=i) ans=min(ans,a+1); //a!=i
}
if (ans>l1||ans>l2) printf("-1
");
else printf("%d
",ans);
}
void solve2()
{
memset(f,0,sizeof(f));
int ans=INF;
for (int i=1;i<=l1;i++) //
{
int a=0;
for (int j=1;j<=l2;j++)
{
if (s[i]==ss[j]) f[i][j]=max(f[i][j],f[i-1][j-1]+1);
else f[i][j]=f[i][j-1];
a=max(a,f[i][j]);
}
if (a!=i) ans=min(ans,a+1);
}
if (ans>l1||ans>l2) printf("-1
");
else printf("%d
",ans);
}
void solve3()
{
memset(l,0x33,sizeof(l));
l[1]=0;
int ans=INF;
for (int i=1;i<=l1;i++)
for (int j=1;j<=sz;j++)
{
int t=ch[j][s[i]-'a'];
if (!t) ans=min(ans,l[j]+1);
else l[t]=min(l[t],l[j]+1);
//l a , i
}
if (ans>l1||ans>l2) printf("-1
");
else printf("%d
",ans);
}
void solve4()
{
memset(l,0x33,sizeof(l));
l[0]=0;
int ans=INF;
for (int i=l2;i>=0;i--)
{
for (int j=0;j<26;j++)
if (mp[j]) c[i][j]=mp[j];
mp[ss[i]-'a']=i;
}
for (int i=1;i<=l1;i++)
for (int j=l2;j>=0;j--)
{
int t=c[j][s[i]-'a'];
if (!t) ans=min(ans,l[j]+1);
else l[t]=min(l[t],l[j]+1);
}
if (ans>l1||ans>l2) printf("-1
");
else printf("%d
",ans);
}
int main()
{
scanf("%s",s+1);
scanf("%s",ss+1); len=strlen(ss+1);
for (int i=1;i<=len;i++) insert(ss[i]-'a');
l1=strlen(s+1); l2=strlen(ss+1);
solve1();
solve2();
solve3();
solve4();
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비슷한 이름의 Attribute를 많이 만들어 삭제하는 Houdini사용 소프트웨어는 Houdini16.5입니다 배열에서는 애트리뷰트의 보간이 잘 동작하지 않는 것과 AttributeCreateSOP 노드에서 Size가 4를 넘는 애트리뷰트를 작성해도 값이 조작할 수 없어 의미가 없...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.