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 }
分类:
{ 动态规划 }
, { 字符串 { Trie树 } }
标签:
OJ题解
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记录一次线上服务OOM排查
· Linux实时系统Xenomai宕机问题的深度定位过程
· 记一次 .NET某汗液测试机系统 崩溃分析
· 深度解析Mamba与状态空间模型:一图带你轻松入门
· 记一次 .NET某电商医药网站 CPU爆高分析
· 《花100块做个摸鱼小网站! 》番外篇—小网站竟然让我赚到钱了
· 学习编程为何会遇到困难?
· Bogus:.NET的假数据生成利器
· 阿里云IP遭受DDOS攻击 快速切换IP实践
· 如何做好软件架构师