数位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;
	}
	
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值