数位DP 记忆化搜索 不要62HDU2089(java实现)
数位dp = dfs + 记忆化
主要思路 1.dfs本是暴力解决问题的一种方法,数位dp是利用动态规划是思想把以前搜索过的过程记录下来,如果到下一次需要这个结果是就可以直接返回这个值,不需要再从新计算了 2.一般我们是从高位往低位搜索,如果我们需要的结果dp数组里面有我们就不需要从新计算了,如果搜索到了个位就返回一(就是本身) 3.还有我们搜索的时候一定要判断是否到达了边界,不然超出我们所要统计的数的范围
HDU2089 AC代码
import java.util.Scanner; public class Main { public static int[] digit; public static long[][] dp; public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()) { long n = sc.nextLong(); long m = sc.nextLong(); if(n==0&&m==0)break; System.out.println(solve(m)-solve(n-1)); } } public static long solve(long sum) { int k = 0; digit = new int[20]; dp = new long[20][2]; while(sum!=0) { digit[++k] = (int) (sum%10); //从1开始复值,0位站位符 sum/=10; } return dfs(k,false,true); //第k位有上限,所以第二个参数是true; } private static long dfs(int len, boolean if6, boolean limit) { if(len==0) return 1; //len=0,统计个位,就是本身 1个 if(!limit&&dp[len][if6?1:0]!=0) return dp[len][if6?1:0]; //记忆化搜索,前面有值的直接返回,就不需要计算了 long cnt = 0,up_bound = limit ? digit[len]:9; //确定dfs的边界 for (int i = 0; i <= up_bound; i++) { //把下面的状态都加起来给当前的状态! if(if6&&i==2) continue; if(i==4) continue; cnt += dfs(len - 1,i==6,limit&&i==up_bound); } if(!limit) dp[len][if6?1:0] = cnt; //这个状态是没有约束条件的 return cnt; } }
下一篇:
JVM操作数栈-运行的过程详解