You are on page 1of 1

Gọi far[i] là vị trí xa nhất mà xâu con (i,far[i]) xuất hiện trong xâu(1,i-1).

Với mỗi i ta sẽ tạo xâu có dạng (i,n)+’#”+(1,i-1); khi đó far[i] sẽ là độ dài tiền tố dài nhất xuất hiện trong
phần xâu (1,i-1). Ta có thể dùng kmp để tính phần này.

Sau đó với mỗi i, ta sẽ có dp[i]=min(dp[i],dp[i-1]+a) và dp[j] j=i+1->far[i+1]=min(dp[j],dp[i]+b).

ĐPT: O(n^2)

Tham khảo code:


#define task "CSTR"
int n,a,b,kmp[N],far[N];
ll dp[N];
string s,x;
int main()
{
if(fopen(task".inp","r"))
{
fin(task".inp");
fout(task".out");
}
srand(time(NULL));
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>a>>b;
cin>>s,s=" "+s;
memset(dp,0x3f,sizeof(dp));
fo(i,2,n)
{
x=s.substr(i,n-i+1)+"#"+s.substr(1,i-1);
fo(k,1,n)
{
int j=kmp[k-1];
while(j>0&&x[j]!=x[k]) j=kmp[j-1];
if(x[k]==x[j]) j++;
kmp[k]=j;
}
fo(j,n-i+2,n) maximize(far[i],kmp[j]);
}
dp[0]=0;
fo(i,1,n)
{
minimize(dp[i],dp[i-1]+a);
fo(j,i+1,i+far[i+1]) minimize(dp[j],dp[i]+b);
}
cout<<dp[n];
}

You might also like