CF798B 1300*
题意
解析
官方解法dp
f[i][j] 代表选到第i个字符串,全都和第i个字符串以j为首开始的部分一样的最小代价
f[i][j] = min(f[i][j],f[i-1][k]+j) (条件是第i-1个字符从k开始的部分和第i个字符串从j开始的部分相同)
答案为f[n][i]里的最小值
第一个字符串有不同种变化,剩下的字符串最终一定要和它某种变化长得一样,全都相同的时侯更新最小值
第一维第1个字符串的不同变化,第二维枚举剩下所有的字符串,第三维枚举剩下的字符串从变化几次开始,第四维判断第1个字符串和第i个字符串是否每一位都一样
代码
//dp O(N*len^3)
#include<bits/stdc++.h>
using namespace std;
const int N = 55;
int n,m,f[N][N];
string s[N];
int main(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> s[i];
if(i == 1) m = s[1].size();
s[i] = s[i] + s[i];
}
memset(f,0x3f,sizeof f);
for(int i=1;i<=m;i++)
f[1][i] = i - 1;
for(int i=2;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=m;k++)
if(s[i].substr(j-1,m) == s[i-1].substr(k-1,m))
f[i][j] = min(f[i][j],f[i-1][k] + j - 1);
int ans = 0x3f3f3f3f;
for(int i=1;i<=m;i++)
ans = min(ans,f[n][i]);
if(ans == 0x3f3f3f3f) cout << -1;
else cout << ans;
return 0;
}
//模拟 O(N*len^3)
int find(int t,int w){
rep(i,0,m-1){
int pf=1;
rep(j,1,m)
if(str[t][i+j]!=str[1][w+j]){
pf=0;
break;
}
if(pf)return i;
}
return 1000000;
}
int main(){
// freopen("1.in","r",stdin);
n=read();
rep(i,1,n){
scanf("%s",str[i]+1);
len[i]=strlen(str[i]+1);
rep(j,1,len[i])str[i][len[i]+j]=str[i][j];
}
rep(i,2,n)
if(len[i]!=len[1]){
puts("-1");
return 0;
}
m=len[1];
int ans=1000000000;
rep(i,0,m-1){
int tot=i;
rep(j,2,n)
tot+=find(j,i);
ans=min(ans,tot);
}
if(ans<10000)cout<<ans<<endl;
else cout<<-1<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】