数位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;
	}
	
}
经验分享 程序员 微信小程序 职场和发展