P6681

==Ambiguous Encoding。orz Wu_ren。

直接选两个拼成的字符串不好刻画,考虑增量。定义一对合法的字符串 S,T 满足其中一个是另一个的前缀(这样才可能通过往后面加模式串变一样),每次往当前两个字符串中长度更短的后面塞一个模式串,使得一个字符串仍是另一个的前缀。

容易发现,任何时刻 ||S||T||m。所以此时可以考虑一个 dp:设 dpi,j 为当前更长的字符串最后的模式串编号为 i||S||T||=j 的状态最少需要多长的字符串拼成。

考虑如何转移:可以枚举一个当前最后模式串编号 i,串长差 j,新接上的模式串编号 k,通过 string 的 substr 函数判断是否可以转移,额外加上的贡献就是新的 max(|S|,|T|) 减之前的。

然而这个转移是有环的,所以把 dp 变为 dis,转化为最短路做。答案即为 mindisi,0

这题自然是可以轻松过的,但是 Ambiguous Encoding 看起来不行(n=1000,m=16),因为这似乎是 O(ElogV)O(n2mlognm) 的。但事实上真是这样的吗?

发现边权不超过 m,所以每个点被松弛的次数也不超过 m,大概可以考虑每个时刻堆里面的数的极差不超过 m。有更好的证明可以教教我。

所以时间复杂度是 O(nmlognm) 的,两题都轻松通过。

细节有一些,尤其注意当第 k 个模式串 |Sk|j 时,dpi,j 还是可能从 k 这里转移的,这一步要注意分讨一下。

code:

点击查看代码
#define ID(i,j) ((i-1)*(m+1)+j+1)
int n,m,dis[N];
string s[N];bool vis[N];
priority_queue<pii> q;
int tot,head[N];
struct node{int to,nxt,cw;}e[M];
il void add(int u,int v,int w){e[++tot]={v,head[u],w},head[u]=tot;}
void Yorushika(){
	scanf("%d%d",&n,&m);
	rep(i,1,n)cin>>s[i];
	rep(i,1,n){
		int l=s[i].size();
		rep(j,0,l-1){
			rep(k,1,n){
				int len=l-j;
				if(k==i&&!j)continue;
				if(s[k].size()>=len){
					if(s[i].substr(j,len)==s[k].substr(0,len)){
						int w=s[k].size()-len;
						add(ID(i,len),ID(k,w),w);
					}
				}else{
					int sz=s[k].size();
					if(s[i].substr(j,sz)==s[k].substr(0,sz)){
						int w=len-sz;
						add(ID(i,len),ID(i,w),0);
					}
				}
			}
		}
	}
	mems(dis,0x3f);
	rep(i,1,n){
		int u=ID(i,s[i].size());
		dis[u]=s[i].size(),q.push(Mp(-dis[u],u));
	}
	while(q.size()){
		int u=q.top().se;q.pop();
		if(vis[u])continue;
		vis[u]=1;
		go(i,u){
			int v=e[i].to;
			if(dis[v]<=dis[u]+e[i].cw)continue;
			dis[v]=dis[u]+e[i].cw,q.push(Mp(-dis[v],v));
		}
	}
	int ans=inf;
	rep(i,1,n)ans=min(ans,dis[ID(i,0)]);
	printf("%d\n",ans<1e9?ans:-1);
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)
		Yorushika();
}
posted @   yinhee  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示