A. 机型超算(boolean)
模拟
B. 字符修改(master)
大水题,暴力枚举两个后缀,计算最长能匹配多少前缀。最优策略一定是贪心改掉前k个失配的字符,这样我们一定能够考虑到所有可能最优的解;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 310;
char s[310], t[310];
int ans;
inline ll read() {
ll x = 0, f = 1;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-')
f = -1, c = getchar();
while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
return f * x;
}
int main() {
freopen("master.in", "r", stdin);
freopen("master.out", "w", stdout);
int n = read(), k = read();
scanf("%s%s", s + 1, t + 1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
int l = i, r = j, cnt = 0;
while (l && r && cnt <= k) {
if (s[l] != t[r]) {
cnt++;
}
l--;
r--;
}
if (cnt > k) {
ans = max(ans, i - l - 1);
} else {
ans = max(ans, i - l);
}
}
}
cout << ans << endl;
return 0;
}
D. 公共子串(lcs)
#include <bits/stdc++.h>
using namespace std;
#define mod 100000000
typedef long long ll;
int dp[3][5100] = {}, g[3][5100] = {};
char s1[5100] = {}, s2[5100] = {};
int main() {
freopen("lcs.in", "r", stdin);
freopen("lcs.out", "w", stdout);
scanf("%s", s1 + 1);
scanf("%s", s2 + 1);
int n = strlen(s1 + 1) - 1, m = strlen(s2 + 1) - 1;
int now = 1, pre = 0;
for (int i = 0; i <= m; i++) {
g[0][i] = 1;
}
g[1][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
g[now][j] = 0;
dp[now][j] = max(dp[pre][j], dp[now][j - 1]);
if (s1[i] == s2[j]) {
dp[now][j] = max(dp[now][j], dp[pre][j - 1] + 1);
}
if (s1[i] == s2[j] && dp[now][j] == dp[pre][j - 1] + 1) {
g[now][j] += g[pre][j - 1];
}
if (dp[pre][j] == dp[now][j]) {
g[now][j] += g[pre][j];
}
if (dp[now][j - 1] == dp[now][j]) {
g[now][j] += g[now][j - 1];
}
if (dp[pre][j - 1] == dp[now][j]) {
g[now][j] -= g[pre][j - 1];
}
g[now][j] = (g[now][j] + mod) % mod;
}
now = pre;
pre = 1 - pre;
}
printf("%d\n%d", dp[pre][m], g[pre][m]);
return 0;
}