[JZOJ 4486] [GDOI 2016 Day 1] 두 번째 문제 최장 공용 꼬치.
Description
두 개의 문자열 S를 주고, T는 N 개의 구간을 주며, S 문자열의 이 구간 내의 문자는 구간의 위치를 마음대로 바꿀 수 있다.S, T가 도달할 수 있는 가장 긴 공통 문자열의 길이를 구합니다.
Analysis
두 바늘로 움직일 수 있습니다. 제가 친 것은 dp입니다.f[i][j]로 S열의 i번째 구간과 T열의 j번째 문자를 나타내는 LCS를 설정합니다.한 무더기의 물건을 미리 처리하고 옮기면 스스로 뇌보한다.
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,b,a) for(int i=b;i>=a;i--)
using namespace std;
const int N=2010;
struct section
{
int l,r;
}a[102010],b[N];
int k,m,n,num,ans,sum['z'+1][N],h['z'+1][N],g[N],f[N][N];
char s[N],t[N];
bool cmp(section a,section b){return a.l<b.l || a.l==b.l && a.r<b.r;}
void pre()
{
int k0;
scanf("%s
%s
%d",t+1,s+1,&k0);
m=strlen(t+1),n=strlen(s+1);
fo(i,1,k0) scanf("%d %d",&a[i].l,&a[i].r),a[i].l++,a[i].r++;
fo(i,1,n) a[++k0].l=a[k0].r=i;
sort(a+1,a+k0+1,cmp);
int l=a[1].l,r=a[1].r;
a[k0+1].l=2147483647;
fo(i,2,k0+1)
if(r>=a[i].l) r=max(r,a[i].r);
else b[++num].l=l,b[num].r=r,g[num]=r-l+1,l=a[i].l,r=a[i].r;
fo(i,1,m)
{
fo(j,'a','z') sum[j][i]=sum[j][i-1];
sum[t[i]][i]++;
}
fo(i,1,num)
fo(j,b[i].l,b[i].r) h[s[j]][i]++;
}
void dp()
{
fd(i,num,1)
fd(j,m,1)
{
bool p=0;
fo(k,j,min(m,j+g[i]-1))
{
if(sum[t[k]][k]-sum[t[k]][j-1]>h[t[k]][i])
{
p=1;
break;
}
else f[i][j]++;
}
if(!p) f[i][j]+=f[i+1][j+g[i]];
int len=0;
fd(k,j-1,max(1,j-g[i-1]))
if(sum[t[k]][j-1]-sum[t[k]][k-1]>h[t[k]][i-1]) break;
else len++;
ans=max(ans,f[i][j]+len);
}
}
int main()
{
freopen("lcs.in","r",stdin);
freopen("lcs.out","w",stdout);
pre();
dp();
printf("%d",ans);
fclose(stdin);fclose(stdout);
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.