-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDigitalDpTemplate.java
More file actions
71 lines (61 loc) · 2.12 KB
/
Copy pathDigitalDpTemplate.java
File metadata and controls
71 lines (61 loc) · 2.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.fqh;
import java.util.Arrays;
/**
* @Author: vq
* @Date: 2023/11/24 11:59
* @Version V1.0
*/
public class DigitalDpTemplate {
public static void main(String[] args) {
}
}
// 不考虑前导零影响的一种题型
class Version1 {
char s[];
int dp[][];
public int countDigitOne(int n) {
s = Integer.toString(n).toCharArray();
var m = s.length;
dp = new int[m][m];
for (var i = 0; i < m; i++) Arrays.fill(dp[i], -1);
return f(0, 0, true);
}
int f(int i, int cnt1, boolean isLimit) {
if (i == s.length) return cnt1;
if (!isLimit && dp[i][cnt1] >= 0) return dp[i][cnt1];
var res = 0;
for (int d = 0, up = isLimit ? s[i] - '0' : 9; d <= up; ++d) // 枚举要填入的数字 d
res += f(i + 1, cnt1 + (d == 1 ? 1 : 0), isLimit && d == up);
if (!isLimit) dp[i][cnt1] = res;
return res;
}
}
// 考虑前导零影响的一种题型
class Version2 {
char s[];
int memo[][];
public int numDupDigitsAtMostN(int n) {
s = Integer.toString(n).toCharArray();
int m = s.length;
memo = new int[m][1 << 10];
for (int i = 0; i < m; i++)
Arrays.fill(memo[i], -1); // -1 表示没有计算过
return n - f(0, 0, true, false);
}
int f(int i, int mask, boolean isLimit, boolean isNum) {
if (i == s.length)
return isNum ? 1 : 0; // isNum 为 true 表示得到了一个合法数字
if (!isLimit && isNum && memo[i][mask] != -1)
return memo[i][mask];
int res = 0;
if (!isNum) // 可以跳过当前数位
res = f(i + 1, mask, false, false);
int up = isLimit ? s[i] - '0' : 9; // 如果前面填的数字都和 n 的一样,那么这一位至多填数字 s[i](否则就超过 n 啦)
for (int d = isNum ? 0 : 1; d <= up; ++d) // 枚举要填入的数字 d
if ((mask >> d & 1) == 0) // d 不在 mask 中
res += f(i + 1, mask | (1 << d), isLimit && d == up, true);
if (!isLimit && isNum)
memo[i][mask] = res;
return res;
}
}