Codeforces 615C Running Track(DP + Trie树)

题目大概说给两个串,问最少要用多少个第一个串的子串(可以翻转)拼成第二个串。

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

 1 #include<cstdio>
 2 #include<cstdlib>
 3 using namespace std;
 4 #define MAXN 2222*2000
 5 
 6 int tn,ch[MAXN][26],from[MAXN],to[MAXN];
 7 
 8 char T[2222],S[2222];
 9 int d[2222],rec[2222];
10 void pnt(int x){
11     if(x<=0) return;
12     pnt(x-abs(from[rec[x]]-to[rec[x]])-1);
13     printf("%d %d\n",to[rec[x]],from[rec[x]]);
14 }
15 int main(){
16     scanf("%s%s",T+1,S+1);
17     int i;
18     for(i=1; T[i]; ++i){
19         int x=0;
20         for(int j=i; T[j]; ++j){
21             int y=T[j]-'a';
22             if(ch[x][y]==0) ch[x][y]=++tn;
23             x=ch[x][y];
24             from[x]=i; to[x]=j;
25         }
26     }
27     for(--i; i>=1; --i){
28         int x=0;
29         for(int j=i; j>=1; --j){
30             int y=T[j]-'a';
31             if(ch[x][y]==0) ch[x][y]=++tn;
32             x=ch[x][y];
33             from[x]=i; to[x]=j;
34         }
35     }
36     rec[0]=1;
37     for(i=1; S[i]; ++i){
38         int x=0;
39         for(int j=i; j>=1; --j){
40             int y=S[j]-'a';
41             if(ch[x][y]==0) break;
42             x=ch[x][y];
43             if(rec[j-1]){
44                 if(d[i]==0 || d[i]>d[j-1]+1){
45                     d[i]=d[j-1]+1;
46                     rec[i]=x;
47                 }
48             }
49         }
50     }
51     if(d[i-1]==0){
52         printf("-1");
53         return 0;
54     }
55     printf("%d\n",d[i-1]);
56     pnt(i-1);
57     return 0;
58 }

 

posted @ 2016-07-17 09:24  WABoss  阅读(346)  评论(0编辑  收藏  举报