萌新求问
查看原帖
萌新求问
292300
Kobe303楼主2022/7/3 18:54

这题为什么不能正着 DP?

我写了一个,正着 DP,状态是 fif_i 表示 S1iS_{1\sim 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;
}
2022/7/3 18:54
加载中...