首页 > 编程语言 >[题解][2021-2022年度国际大学生程序设计竞赛第10届陕西省程序设计竞赛] Type The Strings

[题解][2021-2022年度国际大学生程序设计竞赛第10届陕西省程序设计竞赛] Type The Strings

时间:2024-04-15 22:12:37浏览次数:26  
标签:打出 竞赛 int 题解 花费 length 字符串 程序设计

题目描述

给定n个字符串,有以下几种操作:

  • 打出一个字符,花费1。
  • 删除一个字符,花费1。
  • 复制并打出一个之前打出过的字符串,花费k。

求打出所有n个字符串的最小花费。
(注意,打出顺序和字符串输入的顺序不必相同)

题解
显然,操作3需要算字符串的最长公共子序列来处理。
这个问题可以转换为最小生成树问题:

  1. 目前已经打出的字符串可以被视为最小生成树中已经加入的节点。
  2. 对于每个字符串,都有两种方式:直接花费length的代价或通过别的点得到。
  3. 对于第一个字符串,一定会直接花费length的代价得到。
  4. 那么,就可以设一个虚点0,向所有点建立权值为各自length的边。
    由于一定至少有一个字符串会直接话费length打出,那么虚点一定会被加入到最小生成树中。
    即最小生成树满足该题的性质。

代码

#include<bits/stdc++.h>
#define  int  long long
using namespace std;
const int N=107;
int l[N],f[N][N],fa[N],en=0,n,k;
string s[N];
struct Edge{
	int u,v,w;
}e[N*N*N];
bool cmp(Edge x,Edge y){
	return x.w<y.w;
}
void adde(int u,int v,int w){
	e[++en].u=u,e[en].v=v,e[en].w=w;
}
int find(int x){
	if(fa[x]==x)return x;
	return fa[x]=find(fa[x]);
}
int lcs(int x,int y){
	for(int i=0;i<=l[x];i++)
		for(int j=0;j<l[y];j++)
			f[i][j]=0;
	for(int i=1;i<=l[x];i++)
		for(int j=1;j<=l[y];j++){
			if(s[x][i-1]==s[y][j-1]){
				f[i][j]=f[i-1][j-1]+1;
			}
			else{
				f[i][j]=max(f[i-1][j],f[i][j-1]);
			}
		}
	return k+l[x]+l[y]-f[l[x]][l[y]]*2;
}
signed main(){
	int ans=0;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		fa[i]=i;
		cin>>l[i];
		cin>>s[i];
		adde(0,i,l[i]);
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<i;j++)
			adde(i,j,lcs(i,j));
	sort(e+1,e+en+1,cmp);
	for(int i=1;i<=en;i++){
		int u=find(e[i].u),v=find(e[i].v);
		if(u==v)continue;
		fa[v]=u;
		ans+=e[i].w;
	}
	cout<<ans<<endl;
	return 0;
}

标签:打出,竞赛,int,题解,花费,length,字符串,程序设计
From: https://www.cnblogs.com/zwzww/p/18137016

相关文章

  • P4298 [CTSC2008] 祭祀 题解
    P4298[CTSC2008]祭祀题解给定DAG,求最长反链长度,最长反链方案,有多少个点可以成为反链上的点。Case1熟知Dilworth定理:偏序集的最长反链的长度等于最小链划分。因为偏序集有传递性,所以我们也需要对DAG做一遍传递闭包。这样可以套用Dilworth定理,最小链划分等于点数减......
  • [题解][2021-2022年度国际大学生程序设计竞赛第10届陕西省程序设计竞赛] Hash
    题目描述给定字符串T,要求求字符串S,满足以下条件:S是T的前缀S和T运行某段代码的哈希值相同(代码见下)T只包含小写字母S和T的长度差不超过50哈希代码://LanguageC++14longlongmod=5999993;longlonggethas(strings){longlongret=0;for(charc:s)ret=......
  • PGSQL 问题解决
    1服务无法启动 这里更改安装目录bin下面例如E:\WorkingSoftware\PostgreSql\16\bin更改权限,下面都改下 2  安装时提示database出错,就初始化下执行以下命令E:\WorkingSoftware\PostgreSql\16\bin\pg_ctl.exe-DE:\WorkingSoftware\PostgreSql\16\dat......
  • 2024小学组AHOI赛后题解
    观看建议调成浅色模式(右下角图标)写前扯一下这次省赛可谓是人才辈出啊。结束前一个半小时就交卷,可见这次考试的难度。后我问他们是不是很有信心AKXX:做了前两题,后两题崩溃了。。。好吧,其实第三题没那么难,不过AK的真没有,听说没有一个人做对。接下来带大家看看这几题。(记得,看......
  • CF1253F Cheap Robot 题解
    首先建立一个超级点\(S\),对于每一个可以充电的点\(u\)都建立一条从\(S\tou\)的边权为\(0\)的有向边。从这个超级点\(S\)开始跑一遍最短路算法,就可以得到每一个点\(u\)至少需要花费多少的电量才可以走到一个充电点。令\(D_i\)表示\(i\)号点最少花费多少可以到一个......
  • LlamaIndex 常见问题解答(FAQ)
     提示:如果您尚未完成,请安装LlamaIndex并完成起步教程。遇到不熟悉的术语时,请参考高层次概念部分。在这个章节中,我们将从您为起步示例编写的代码开始,展示您可能希望针对不同应用场景对其进行的常见定制方法:python fromllama_index.coreimportVectorStoreIndex,Simp......
  • P4383 林克卡特树 题解
    题意:给定带边权的树,要切掉\(k\)条边,再任意连上\(k\)条边权为\(0\)的边。问最优策略下得到的树的边权最大值。\(n,k\le3\times10^5\)。参考【问题转化】切掉\(k\)条边后会变成\(k+1\)个连通块,之后的连边一定会把这\(k+1\)个连通块的直径连起来。所以相当于问把......
  • [题解](A-G)Atcoder Educational DP Contest(更新中)
    AtcoderEducationalDPContest\(\textbf{A.Frog1}\)对于一块石头\(i(3\lei\leN)\),\(i-1\)和\(i-2\)均能到达。用\(f[i]\)表示跳到第\(i\)个石头用的最小体力消耗:\[f[i]=min(abs(h[i]-h[i-1])+f[i-1],abs(h[i]-h[i-2])+f[i-2])\qquadi\ge3\]时间复杂度\(O(n)\)。......
  • 华中农业大学第十三届程序设计竞赛 题解
    A-scx的散文诗句Solution正负分开来分别处理,按照绝对值从大到小排序,两两匹配注意:当没有\(0\)且正数和负数都为奇数,即最后剩下一个正数一个负数时,必须匹配Code#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;voidsolve(){intn;cin>......
  • [题解]P1629 邮递员送信
    好久不写图论题了,Dijkstra都花了好长时间捡起来……之前也没有接触过反图的概念。这个题算是我重拾图论知识以来的第一题了。__φ(..)P1629邮递员送信Dijkstra是单源最短路的算法。但这个题除了要求节点\(1\)到其他节点的距离,还要知道其他节点回到节点\(1\)的距离。如果我们每个......