建立自己的代码风格比建立自己的思想体系更加困难,就像思考的时候习惯从0开始和从1开始的差异会导致好多步骤不一样。这个代码模仿kuangbin大佬
链接如下 https://www.cnblogs.com/kuangbin/p/3164106.html
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10,INF = 0x3f3f3f3f;
char str[N];
int dp[1010][1010];
int getid(char c)
{
if(c == 'A') return 0;
if(c == 'C') return 1;
if(c == 'G') return 2;
if(c == 'T') return 3;
}
struct Trie{
int nxt[N][4],fail[N],end[N];
int rt,tot;
int newnode()
{
for(int i = 0; i < 26; ++i) nxt[tot][i] = -1;
end[tot] = 0;
return tot++;
}
void init()
{
tot = 0;
rt = newnode();
}
void insert(char *str)
{
int p = rt;
for(int i = 0; str[i]; ++i)
{
if(nxt[p][getid(str[i])] == -1) nxt[p][getid(str[i])] = newnode();
p = nxt[p][getid(str[i])];
}
end[p] = 1;
}
void build()
{
queue<int> q;
fail[rt] = rt;
for(int i = 0; i < 4; ++i)
if(nxt[rt][i] == -1) nxt[rt][i] = rt;
else
{
fail[nxt[rt][i]] = rt;
q.push(nxt[rt][i]);
}
while(!q.empty())
{
int fa = q.front(); q.pop();
if(end[fail[fa]]) end[fa] = 1;
for(int i = 0; i < 4; ++i)
if(nxt[fa][i] == -1) nxt[fa][i] = nxt[fail[fa]][i];
else
{
fail[nxt[fa][i]] = nxt[fail[fa]][i];
q.push(nxt[fa][i]);
}
}
}
int solve(char *str)
{
int len = strlen(str);
for(int i = 0; i <= len; ++i)
for(int j = 0; j < tot; ++j) dp[i][j] = INF;
dp[0][rt] = 0;
for(int i = 0; str[i]; ++i)
for(int j = 0; j < tot; ++j)
{
if(dp[i][j] >= INF) continue;
for(int k = 0; k < 4; ++k)
{
if(end[nxt[j][k]]) continue;
dp[i+1][nxt[j][k]] = min(dp[i+1][nxt[j][k]],dp[i][j]+(getid(str[i])==k?0:1));
}
}
int ans = INF;
for(int j = 0; j < tot; ++j) ans = min(ans,dp[len][j]);
if(ans == INF) return -1;
return ans;
}
}ac;
int main()
{
int n;
int cas = 0;
while(cin >> n && n)
{
ac.init();
for(int i = 0; i < n; ++i)
{
scanf("%s",str);
ac.insert(str);
}
ac.build();
scanf("%s",str);
printf("Case %d: %d\n",++cas,ac.solve(str));
}
}
喜欢从1开始的正常吗。。。
啊这,完全看具体问题吧,前缀和就从1开始比较好