博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 4032 trie树+各种乱搞
阅读量:6086 次
发布时间:2019-06-20

本文共 2326 字,大约阅读时间需要 7 分钟。

思路 :

先对b 的所有后缀建立trie树

第一问

暴力枚举a串的起点

在trie树上跑 找到最短的

第二问

也是暴力枚举a串的起点

a和b顺着暴力匹配就好

第三问

求出来a在第i个位置 加一个字母j 能够到的最近的位置 f[i][j] 到最后就是inf

从f[0][j]DFS 在trie上跟着跑找到最小的deep更新答案

第四问

先按照求f一样同理求出b串 的  g

dp[i][j]表示a的前i个位置 b不得不匹配到b的第j个位置

            
dp[i+1][j]=min(dp[i+1][j],dp[i][j]),
            
dp[i+1][g[j][a[i]]]=min(dp[i+1][g[j][a[i]]],dp[i][j]+1);
1—>strlen(a)+1 min dp[i][inf]就是答案
 
这题看起来简单  其实感觉在考场根本写不出来...
 
//By SiriusRen#include 
#include
#include
using namespace std;const int N=2050,inf=2010;int ch[N*N/2][27],f[N][27],g[N][27],dp[N][N],cnt,ans1,ans2,ans3,ans4,vis[27];void insert(char *a){ int now=0; for(int i=0;a[i];i++){ if(!ch[now][a[i]])ch[now][a[i]]=++cnt; now=ch[now][a[i]]; }}int solve1(char *a){ int now=0,i; for(i=0;a[i];i++){ if(!ch[now][a[i]])return i+1; else now=ch[now][a[i]]; }return inf;}void solve3(int x,int now,int deep){ if(x==inf)return; if(!now&&deep){ans3=min(ans3,deep);return;} for(int i=1;i<=26;i++)solve3(f[x][i],ch[now][i],deep+1);}char a[N],b[N];int main(){ scanf("%s%s",a+1,b+1); int n1=strlen(a+1),n2=strlen(b+1); for(int i=1;i<=n1;i++)a[i]=a[i]-'a'+1; for(int i=1;i<=n2;i++)b[i]=b[i]-'a'+1; for(int i=1;i<=n2;i++)insert(b+i); ans1=ans2=ans3=ans4=inf; for(int i=1;i<=n1;i++)ans1=min(ans1,solve1(a+i)); for(int i=1;i<=n1;i++){ int now=1; for(int j=0;i+j<=n1;now++,j++){ while(a[i+j]!=b[now]&&now<=n2)now++; if(now>n2){ans2=min(ans2,j+1);break;} } } for(int i=0;i<=n1;i++){ memset(vis,0,sizeof(vis)); for(int j=i+1;j<=n1;j++)if(!vis[a[j]])vis[a[j]]=j; for(int j=1;j<=26;j++)f[i][j]=vis[j]?vis[j]:inf; }solve3(0,0,0); for(int i=0;i<=n2;i++){ memset(vis,0,sizeof(vis)); for(int j=i+1;j<=n2;j++)if(!vis[b[j]])vis[b[j]]=j; for(int j=1;j<=26;j++)g[i][j]=vis[j]?vis[j]:inf; } memset(dp,0x3f,sizeof(dp)),dp[0][0]=0; for(int i=0;i<=n1;i++) for(int j=0;j<=n2;j++) dp[i+1][j]=min(dp[i+1][j],dp[i][j]), dp[i+1][g[j][a[i]]]=min(dp[i+1][g[j][a[i]]],dp[i][j]+1); for(int i=1;i<=n1+1;i++)ans4=min(ans4,dp[i][inf]); printf("%d\n%d\n%d\n%d\n",ans1==inf?-1:ans1,ans2==inf?-1:ans2,ans3==inf?-1:ans3,ans4==inf?-1:ans4);}

 

转载于:https://www.cnblogs.com/SiriusRen/p/6592621.html

你可能感兴趣的文章
css知多少(8)——float上篇
查看>>
NLB网路负载均衡管理器详解
查看>>
水平添加滚动条
查看>>
PHP中”单例模式“实例讲解
查看>>
VS2008查看dll导出函数
查看>>
VM EBS R12迁移,启动APTier . AutoConfig错误
查看>>
atitit.细节决定成败的适合情形与缺点
查看>>
Mysql利用binlog恢复数据
查看>>
我的友情链接
查看>>
用yum安装mariadb
查看>>
一点IT"边缘化"的人的思考
查看>>
WPF 降低.net framework到4.0
查看>>
搭建一个通用的脚手架
查看>>
开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
查看>>
开源磁盘加密软件VeraCrypt教程
查看>>
本地vs云:大数据厮杀的最终幸存者会是谁?
查看>>
阿里云公共镜像、自定义镜像、共享镜像和镜像市场的区别 ...
查看>>
shadowtunnel v1.7 发布:新增上级负载均衡支持独立密码
查看>>
Java线程:什么是线程
查看>>
mysql5.7 创建一个超级管理员
查看>>