デジタルDP
トピック | 知識ポイント | 困難 |
---|---|---|
2376. 特殊な整数を数える | デジタルDPテンプレート | 困難 |
600. 連続する 1 のない非負の整数 | デジタルDP | 困難 |
233. 1の数 | デジタル DDP テンプレートの質問 | 困難 |
902. 最大 N 個の数字の組み合わせ | デジタル DDP テンプレートのトピック | 困難 |
1の数 | マスクは数値 x の数を記録します | |
アクウィング数 1081度 | 基本的な考え方を使用し、各ビットは 1 または 0 です。マスクレコード数 1 | |
アクウィング 1082、1083 、1085 | マスクレコードの最初の桁の番号は何ですか | |
反応する 1084 | マスクは前の数値の合計を記録します | |
デジタル DDP の質問を行うためのアイデア
まず、[a, b] 間隔を [0, a]、[0, b] からの 1 回の計算に変更します。それから違いを生む
次に、標準のテンプレート コードを使用します。
標準テンプレート コードは、トピックで定義された条件に従って、pre state 変数を変更するだけです。
一般的な状態変数は次のとおりです。
- 前のトピックでは、このトピックの隣接する数字の間に割り算の数字があります。acwingの1082、1083、1085など
- 桁の合計、acwing 1084 の場合を参照
- マスクでは、1 ~ 9 の数字を繰り返すことはできません。マスク レコードがその番号を選択します
- cntx cnt_xできない_×、x の出現数は、出現数をカウントするために使用されます。符号の数 1
private static int dfs(int cur, int pre, boolean isNum, boolean isLimit) {
if (cur == s.length) {
return isNum ? 1 : 0;
}
// 记忆化
int res = dp[cur][pre];
if (isNum && !isLimit && res >= 0)
return res;
res = 0;
// 不是数字,可以跳过
if (!isNum) res += dfs(cur + 1, pre, false, false);
// 枚举是数字的情况
int up = isLimit ? s[cur] - '0' : 9;
for (int i = isNum ? 0 : 1; i <= up; i++) {
if (i == 4 || (pre == 6 && i == 2)) continue;
res += dfs(cur + 1, i, true, isLimit && i == up);
}
// 记录
if (!isLimit && isNum) dp[cur][pre] = res;
return res;
}