题意:给定长度为
slen
的字符串
A
,和
思路:区间dp
f[i][j][k][l]
为从
i
到
can[i][j]
为
i到j
能否全部删除。
#include <bits/stdc++.h>
#include <ctime>
//#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int L = 160;
const int N = 43;
const int P = 33;
bool f[L][L][N][P];
bool can[L][L];
int n, len[N], slen, dp[L];
char s[N][P], ss[L];
int main()
{
while (scanf("%s", ss+1) != EOF)
{
memset(f, 0, sizeof f);
memset(can, 0, sizeof can);
slen = strlen(ss+1);
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%s", s[i] + 1);
len[i] = strlen(s[i] + 1);
}
for (int i = slen; i >= 1; i--)
{
for (int j = i; j <= slen; j++)
{
for (int k = 1; k <= n; k++)
{
f[i][i - 1][k][0] = true;
for (int l = 1; l <= len[k] && l <= j - i + 1; l++)
{
if (f[i][j - 1][k][l - 1] && s[k][l] == ss[j])
f[i][j][k][l] = true;
for (int tmp = i; tmp < j; tmp++)
if (f[i][tmp][k][l] && can[tmp + 1][j])
f[i][j][k][l] = true;
}
}
for (int k = 1; k <= n; k++)
{
if (f[i][j][k][len[k]])
{
can[i][j] = true;
break;
}
}
}
}
for (int i = 1; i <= slen; i++)
{
dp[i] = dp[i - 1] + 1;
for (int j = i; j >= 1; j--)
{
if (can[j][i])dp[i] = min(dp[i], dp[j - 1]);
}
}
printf("%d\n", dp[slen]);
}
}