Codeforces 1163D Mysterious Code
题目链接
https://codeforces.com/contest/1163/problem/D
题目大意
给你一个字符串 c ,你可以将其中的 ‘*’ 换成任意的字符,你需要最大化字符串 s 和 t 在其中出现的次数的差值。
题目分析
这题比较明显是个 KMP + DP 的题。定义 f[i][j][k] 为到第 i 个字符,匹配到 s_j 和 t_k 的最大差值为多少,那么可以从这个歌状态转移到添加完新的字符后在 KMP 上的新的位置,加入匹配上的话需要根据情况 +1 或者 -1 。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
int inf = 0x3f3f3f3f;
int n, m, t;
string a, b, str;
int na[55];
int nb[55];
int f[1005][55][55];
int read(){
int x;
scanf("%d", &x);
return x;
}
int getnext(){
int i, j;
na[0] = 0;
na[1] = 0;
for(i=2;i<=n;i++){
j = na[i - 1];
while(j and a[j + 1] != a[i]){
j = na[j];
}
if(a[j + 1] == a[i]){
na[i] = j + 1;
}else{
na[i] = 0;
}
}
nb[0] = 0;
nb[1] = 0;
for(i=2;i<=m;i++){
j = nb[i - 1];
while(j and b[j + 1] != b[i]){
j = nb[j];
}
if(b[j + 1] == b[i]){
nb[i] = j + 1;
}else{
nb[i] = 0;
}
}
return 0;
}
int main(){
int i, j, k, l;
int x, y;
cin >> str >> a >> b;
n = a.length();
m = b.length();
a = '0' + a;
b = '0' + b;
str = '0' + str;
getnext();
for(i=0;i<=str.length();i++){
for(j=0;j<=n;j++){
for(k=0;k<=m;k++){
f[i][j][k] = -inf;
}
}
}
f[0][0][0] = 0;
for(i=1;i<str.length();i++){
for(j=0;j<n;j++){
for(k=0;k<m;k++){
if(str[i] != '*'){
int tmp = f[i - 1][j][k];
x = j, y = k;
bool flag = false;
if(str[i] == a[x + 1]){
if(x + 1 == n){
tmp++;
x = na[x + 1];
flag = true;
}
}else{
x = na[x];
while(x and str[i] != a[x + 1]){
x = na[x];
}
}
if(!flag and str[i] == a[x + 1]){
x++;
}
flag = false;
if(str[i] == b[y + 1]){
if(y + 1 == m){
tmp--;
y = nb[y + 1];
flag = true;
}
}else{
y = nb[y];
while(y and str[i] != b[y + 1]){
y = nb[y];
}
}
if(!flag and str[i] == b[y + 1]){
y++;
}
f[i][x][y] = max(f[i][x][y], tmp);
}else{
for(l=0;l<26;l++){
int tmp = f[i - 1][j][k];
x = j, y = k;
bool flag = false;
if('a' + l == a[x + 1]){
if(x + 1 == n){
tmp++;
x = na[x + 1];
flag = true;
}
}else{
x = na[x];
while(x and 'a' + l != a[x + 1]){
x = na[x];
}
}
if(!flag and 'a' + l == a[x + 1]){
x++;
}
flag = false;
if('a' + l == b[y + 1]){
if(y + 1 == m){
tmp--;
y = nb[y + 1];
flag = true;
}
}else{
y = nb[y];
while(y and 'a' + l != b[y + 1]){
y = nb[y];
}
}
if(!flag and 'a' + l == b[y + 1]){
y++;
}
f[i][x][y] = max(f[i][x][y], tmp);
}
}
}
}
}
int ans = -inf;
for(j=0;j<n;j++){
for(k=0;k<m;k++){
ans = max(ans, f[str.length() - 1][j][k]);
}
}
cout << ans << endl;
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
int inf = 0x3f3f3f3f;
int n, m, t;
string a, b, str;
int na[55];
int nb[55];
int f[1005][55][55];
int read(){
int x;
scanf("%d", &x);
return x;
}
int getnext(){
int i, j;
na[0] = 0;
na[1] = 0;
for(i=2;i<=n;i++){
j = na[i - 1];
while(j and a[j + 1] != a[i]){
j = na[j];
}
if(a[j + 1] == a[i]){
na[i] = j + 1;
}else{
na[i] = 0;
}
}
nb[0] = 0;
nb[1] = 0;
for(i=2;i<=m;i++){
j = nb[i - 1];
while(j and b[j + 1] != b[i]){
j = nb[j];
}
if(b[j + 1] == b[i]){
nb[i] = j + 1;
}else{
nb[i] = 0;
}
}
return 0;
}
int main(){
int i, j, k, l;
int x, y;
cin >> str >> a >> b;
n = a.length();
m = b.length();
a = '0' + a;
b = '0' + b;
str = '0' + str;
getnext();
for(i=0;i<=str.length();i++){
for(j=0;j<=n;j++){
for(k=0;k<=m;k++){
f[i][j][k] = -inf;
}
}
}
f[0][0][0] = 0;
for(i=1;i<str.length();i++){
for(j=0;j<n;j++){
for(k=0;k<m;k++){
if(str[i] != '*'){
int tmp = f[i - 1][j][k];
x = j, y = k;
bool flag = false;
if(str[i] == a[x + 1]){
if(x + 1 == n){
tmp++;
x = na[x + 1];
flag = true;
}
}else{
x = na[x];
while(x and str[i] != a[x + 1]){
x = na[x];
}
}
if(!flag and str[i] == a[x + 1]){
x++;
}
flag = false;
if(str[i] == b[y + 1]){
if(y + 1 == m){
tmp--;
y = nb[y + 1];
flag = true;
}
}else{
y = nb[y];
while(y and str[i] != b[y + 1]){
y = nb[y];
}
}
if(!flag and str[i] == b[y + 1]){
y++;
}
f[i][x][y] = max(f[i][x][y], tmp);
}else{
for(l=0;l<26;l++){
int tmp = f[i - 1][j][k];
x = j, y = k;
bool flag = false;
if('a' + l == a[x + 1]){
if(x + 1 == n){
tmp++;
x = na[x + 1];
flag = true;
}
}else{
x = na[x];
while(x and 'a' + l != a[x + 1]){
x = na[x];
}
}
if(!flag and 'a' + l == a[x + 1]){
x++;
}
flag = false;
if('a' + l == b[y + 1]){
if(y + 1 == m){
tmp--;
y = nb[y + 1];
flag = true;
}
}else{
y = nb[y];
while(y and 'a' + l != b[y + 1]){
y = nb[y];
}
}
if(!flag and 'a' + l == b[y + 1]){
y++;
}
f[i][x][y] = max(f[i][x][y], tmp);
}
}
}
}
}
int ans = -inf;
for(j=0;j<n;j++){
for(k=0;k<m;k++){
ans = max(ans, f[str.length() - 1][j][k]);
}
}
cout << ans << endl;
return 0;
}
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <string> #include <algorithm> using namespace std; int inf = 0x3f3f3f3f; int n, m, t; string a, b, str; int na[55]; int nb[55]; int f[1005][55][55]; int read(){ int x; scanf("%d", &x); return x; } int getnext(){ int i, j; na[0] = 0; na[1] = 0; for(i=2;i<=n;i++){ j = na[i - 1]; while(j and a[j + 1] != a[i]){ j = na[j]; } if(a[j + 1] == a[i]){ na[i] = j + 1; }else{ na[i] = 0; } } nb[0] = 0; nb[1] = 0; for(i=2;i<=m;i++){ j = nb[i - 1]; while(j and b[j + 1] != b[i]){ j = nb[j]; } if(b[j + 1] == b[i]){ nb[i] = j + 1; }else{ nb[i] = 0; } } return 0; } int main(){ int i, j, k, l; int x, y; cin >> str >> a >> b; n = a.length(); m = b.length(); a = '0' + a; b = '0' + b; str = '0' + str; getnext(); for(i=0;i<=str.length();i++){ for(j=0;j<=n;j++){ for(k=0;k<=m;k++){ f[i][j][k] = -inf; } } } f[0][0][0] = 0; for(i=1;i<str.length();i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ if(str[i] != '*'){ int tmp = f[i - 1][j][k]; x = j, y = k; bool flag = false; if(str[i] == a[x + 1]){ if(x + 1 == n){ tmp++; x = na[x + 1]; flag = true; } }else{ x = na[x]; while(x and str[i] != a[x + 1]){ x = na[x]; } } if(!flag and str[i] == a[x + 1]){ x++; } flag = false; if(str[i] == b[y + 1]){ if(y + 1 == m){ tmp--; y = nb[y + 1]; flag = true; } }else{ y = nb[y]; while(y and str[i] != b[y + 1]){ y = nb[y]; } } if(!flag and str[i] == b[y + 1]){ y++; } f[i][x][y] = max(f[i][x][y], tmp); }else{ for(l=0;l<26;l++){ int tmp = f[i - 1][j][k]; x = j, y = k; bool flag = false; if('a' + l == a[x + 1]){ if(x + 1 == n){ tmp++; x = na[x + 1]; flag = true; } }else{ x = na[x]; while(x and 'a' + l != a[x + 1]){ x = na[x]; } } if(!flag and 'a' + l == a[x + 1]){ x++; } flag = false; if('a' + l == b[y + 1]){ if(y + 1 == m){ tmp--; y = nb[y + 1]; flag = true; } }else{ y = nb[y]; while(y and 'a' + l != b[y + 1]){ y = nb[y]; } } if(!flag and 'a' + l == b[y + 1]){ y++; } f[i][x][y] = max(f[i][x][y], tmp); } } } } } int ans = -inf; for(j=0;j<n;j++){ for(k=0;k<m;k++){ ans = max(ans, f[str.length() - 1][j][k]); } } cout << ans << endl; return 0; }