// 入门数位DP
我就说肯定能用一维DP数组求解,结果连续WA了两天,最后对数逐位分析发现,java代码中全局变量没有赋到值...
由于本题是入门性数位DP,状态是用一维存储,故大多数题解是线性递推求解的。
【拓展】
- 数位DP的复杂度为O(状态数*转移数) //状态数是dp数组的大小,转移数是for循环大小
- 数位dp总结之从入门到模板 https://blog.csdn.net/wust_zzwh/article/details/52100392
import java.util.Arrays; import java.util.Scanner; public class Solution { static int[] a = new int[10]; static int[] dp = new int[10]; static int[] pow = new int[10]; static int N; public static int dfs(int pos, boolean limit) { if (pos == -1) { return 0; } if (!limit && dp[pos] != -1) { return dp[pos]; } int up = limit ? a[pos] : 9; int ans = 0; for (int i = 0; i <= up; i++) { if (i == 1) { if (limit && i == a[pos]) { ans += N % pow[pos] + 1; } else { ans += pow[pos]; } } int flag = dfs(pos - 1, limit && i == a[pos]); ans += flag; } if (!limit) { dp[pos] = ans; } return ans; } public static int NumberOf1Between1AndN_Solution(int n) { int pos = 0; N = n; while (n > 0) { a[pos++] = n % 10; n /= 10; } Arrays.fill(dp, -1); pow[0] = 1; for (int i = 1; i < pow.length; i++) { pow[i] = pow[i - 1] * 10; } return dfs(pos - 1, true); } public static void main(String[] args) { while (true) { int n = new Scanner(System.in).nextInt(); System.out.println(NumberOf1Between1AndN_Solution(n)); } } }