专栏文章
题解:P12124 [蓝桥杯 2024 省 B 第二场] 前缀总分
P12124题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miod15py
- 此快照首次捕获于
- 2025/12/02 17:12 3 个月前
- 此快照最后确认于
- 2025/12/02 17:12 3 个月前
题意简述
给定 个字符串 ,修改某字符串的某个字符,使 最大。 为字符串 的最长公共前缀长度。
思路
考虑 dp。定义 表示 和 从第 位开始到结尾的子串的最长公共前缀长度。
状态转移:
统计答案时,我们枚举要修改的字符串编号 ,修改字符的下标 和修改后的字符 。记这次修改可以使答案增加 。对于所有 ,有以下两种情况使答案变动:
-
如果 且 ,这说明原本 和 相等的部分在第 位这里断开了,修改之后可以给它接上。。
-
如果 且 ,这说明原本 和 有一个较长的最长公共前缀,我们这次修改给它破坏了。。
记原本不加修改的答案为 。则 即为最终答案。时间复杂度 ,其中 。
代码
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 205;
string s[N];
int f[N][N][N];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> s[i];
s[i] = " " + s[i];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = min(s[i].size(), s[j].size())-1; k >= 1; k--)
if (s[i][k] == s[j][k])
f[i][j][k] = f[i][j][k+1] + 1;
int ans0 = 0;
for (int i = 1; i <= n; i++)
for (int j = i+1; j <= n; j++)
ans0 += f[i][j][1];
int ans = ans0;
for (int i = 1; i <= n; i++) {
for (int k = 1; k < s[i].size(); k++) {
for (char c = 'a'; c <= 'z'; c++) {
int add = 0;
for (int j = 1; j <= n; j++) {
if (j == i || k >= s[j].size()) continue;
if (f[i][j][1] == k-1 && c == s[j][k])
add += f[i][j][k+1]+1;
if (f[i][j][1] >= k && c != s[j][k])
add -= f[i][j][1]-k+1;
}
ans = max(ans, ans0+add);
}
}
}
cout << ans << endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...