您的位置:首页 > 其它

Codeforces 615C Running Track(DP + Trie树)

2016-07-17 09:24 302 查看
题目大概说给两个串,问最少要用多少个第一个串的子串(可以翻转)拼成第二个串。

UVa1401,一个道理。。dp[i]表示前缀i拼接成功所需最少的子串,利用第一个串所有子串建立的Trie树往前枚举转移。

#include<cstdio>
#include<cstdlib>
using namespace std;
#define MAXN 2222*2000

int tn,ch[MAXN][26],from[MAXN],to[MAXN];

char T[2222],S[2222];
int d[2222],rec[2222];
void pnt(int x){
if(x<=0) return;
pnt(x-abs(from[rec[x]]-to[rec[x]])-1);
printf("%d %d\n",to[rec[x]],from[rec[x]]);
}
int main(){
scanf("%s%s",T+1,S+1);
int i;
for(i=1; T[i]; ++i){
int x=0;
for(int j=i; T[j]; ++j){
int y=T[j]-'a';
if(ch[x][y]==0) ch[x][y]=++tn;
x=ch[x][y];
from[x]=i; to[x]=j;
}
}
for(--i; i>=1; --i){
int x=0;
for(int j=i; j>=1; --j){
int y=T[j]-'a';
if(ch[x][y]==0) ch[x][y]=++tn;
x=ch[x][y];
from[x]=i; to[x]=j;
}
}
rec[0]=1;
for(i=1; S[i]; ++i){
int x=0;
for(int j=i; j>=1; --j){
int y=S[j]-'a';
if(ch[x][y]==0) break;
x=ch[x][y];
if(rec[j-1]){
if(d[i]==0 || d[i]>d[j-1]+1){
d[i]=d[j-1]+1;
rec[i]=x;
}
}
}
}
if(d[i-1]==0){
printf("-1");
return 0;
}
printf("%d\n",d[i-1]);
pnt(i-1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: