这题为什么不能正着 DP?
我写了一个,正着 DP,状态是 fi 表示 S1∼i 分解的方案数,然后转移枚举前面可以用字典里的哪个,不说时间复杂度劣的事情,就问一句为什么会 WA 而且题解区清一色是倒着 DP。
Code:
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int N = 300005, mod = 20071027;
int n, m;
char s[N], t[105];
ull p[N], f[N], val[N];
int len[105];
int dp[N];
int Case;
void add(int &a, int b) {
a += b;
if (a >= mod) a -= mod;
}
void solve() {
memset(dp, 0, sizeof dp);
dp[0] = 1;
n = strlen(s + 1);
for (int i = 1; i <= n; ++i) f[i] = f[i - 1] * 131 + (s[i] - 'a' + 1);
scanf("%d", &m);
for (int i = 1; i <= m; ++i) {
scanf("%s", t + 1);
val[i] = 0;
len[i] = strlen(t + 1);
for (int j = 1; j <= len[i]; ++j) val[i] = val[i] * 131 + (t[j] - 'a' + 1);
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (i < len[j]) continue;
if (f[i] - f[i - len[j]] * p[len[j]] == val[j]) add(dp[i], dp[i - len[j]]);
}
}
printf("Case %d: %d\n", ++Case, dp[n]);
}
int main() {
p[0] = 1;
for (int i = 1; i <= 300000; ++i) p[i] = p[i - 1] * 131;
while (~scanf("%s", s + 1)) solve();
return 0;
}