[DP] 數位DP

Peppa_Even_Pig發表於2024-07-14

本文主要內容:數位DP例題

數位DP

主要有兩種方法,填數法和記搜。這裡主要研究記搜的實現;

模板

相比於填數法,記搜的優點在於有固定的模板,實現較容易;

缺點在於需要很多 $ memset $,常數較大,容易被卡;

下面透過幾道例題來了解記搜模板;

一 $ haha $ 數

image

設記搜各引數如下:

long long dfs(int x, int gcd, bool limit, int st)

$ gcd $ 代表各位數字的最小公倍數,$ limit $ 代表當前位有沒有到達最高位限制,$ st $ 代表現在的數 $ mod \ 2520 $ 的結果($ 2520 $ 是數字$ 1 \ to \ 9 $ 的和);

$ gcd $ 可以離散化($ 2520 $ 的因數最多隻有不到 $ 50 $ 個);

long long dfs(int x, int gcd, bool limit, int st) {
	if (x > cnt) return st % gcd == 0;
	if (!limit && f[cnt - x + 1][vis[gcd]][st] != -1) return f[cnt - x + 1][vis[gcd]][st];
	int res = limit ? a[cnt - x + 1] : 9; //判斷現在的限制;
	long long ret = 0;
	for (register int i = 0; i <= res; i++) {
		if (i == 0) ret += dfs(x + 1, gcd, limit && i == res, st * 10 % mod); //特判0;
		else ret += dfs(x + 1, gcd * i / __gcd(gcd, i), limit && i == res, (st * 10 + i) % mod);
	}
	return limit ? ret : f[cnt - x + 1][vis[gcd]][st] = ret;
}

也是水了一篇