题解 S
KMP自动机,需要预处理优化跳next的过程
- 特别注意CCF的arbiter算空间的时候是按MB而不是MiB算的,256MB折合下来只有244MiB多点
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 8010
#define ll long long
//#define int long long
int n, m;
char s[N], t[N];
namespace force{
int ans=INF, nxt[N], top;
char sta[N];
bool check() {
for (int i=1,j=0; i<=top; ++i) {
while (j && (j==m||sta[i]!=t[j+1])) j=nxt[j];
if (sta[i]==t[j+1]) ++j;
if (j==m) return 1;
}
// cout<<"top: "<<top<<endl;
// cout<<"sta: "; for (int i=1; i<=top; ++i) cout<<sta[i]; cout<<endl;
return 0;
}
void solve() {
nxt[1]=0;
for (int i=2,j=0; i<=m; ++i) {
while (j && t[j+1]!=t[i]) j=nxt[j];
if (t[j+1]==t[i]) ++j;
nxt[i]=j;
}
int lim=1<<n;
for (int s0=0,s2,cnt; s0<lim; ++s0) {
s2=s0; cnt=0; top=0;
if (s0) do {s2&=s2-1; ++cnt;} while (s2);
if (n-cnt>=ans) continue;
for (int i=0; i<n; ++i) if (s0&(1<<i)) sta[++top]=s[i+1];
if (!check()) ans=min(ans, n-cnt);
}
printf("%d\n", ans);
exit(0);
}
}
namespace task1{
short nxt[N], dp[8010][8010], st[8010][26], ans=16380;
const short one=1;
inline short min(short a, short b) {return a>b?b:a;}
void solve() {
memset(dp, 0x3f, sizeof(dp));
// cout<<dp[1][1]<<endl;
// cout<<double(sizeof(nxt)+sizeof(dp)+sizeof(st)+sizeof(s)*2+sizeof(force::nxt)+sizeof(force::sta))/1024/1024<<endl;
nxt[1]=0;
for (int i=2,j=0; i<=m; ++i) {
while (j && t[j+1]!=t[i]) j=nxt[j];
if (t[j+1]==t[i]) ++j;
nxt[i]=j;
}
for (int i=0; i<m; ++i) {
for (int j=0,p; j<26; ++j) {
p=i;
while (p && j!=t[p+1]-'a') p=st[nxt[p]][j];
// if (t[p+1]-'a'==j) ++p;
st[i][j]=p;
}
}
dp[1][0]=0;
for (int i=1; i<=n; ++i) {
for (int j=0,j2; j<m; ++j) {
if (s[i]==t[j+1]) {
if (j+1<m) dp[i+1][j+1]=min(dp[i+1][j+1], dp[i][j]);
dp[i+1][j]=min(dp[i+1][j], dp[i][j]+one);
}
else {
dp[i+1][j]=min(dp[i+1][j], dp[i][j]+one);
j2=st[j][s[i]-'a'];
if (t[j2+1]==s[i]) ++j2;
dp[i+1][j2]=min(dp[i+1][j2], dp[i][j]);
}
}
}
// for (int i=1; i<=n+1; ++i) for (int j=0; j<m; ++j) printf("dp[%d][%d]=%d\n", i, j, dp[i][j]);
for (int i=0; i<m; ++i) ans=min(ans, dp[n+1][i]);
printf("%d\n", ans);
exit(0);
}
}
signed main()
{
freopen("s.in", "r", stdin);
freopen("s.out", "w", stdout);
// cout<<double(sizeof(tem))/1024/1024<<endl;
scanf("%s%s", s+1, t+1);
n=strlen(s+1); m=strlen(t+1);
// force::solve();
task1::solve();
return 0;
}