NB群友

一开始解不出来 看了c++语言版本 改写成java版本老失败 后面宿友廖某MVP改出来了

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
  
public class Main {
  
    static Map<Long, Long> map = new HashMap<>();

    public static long dfs(long x) {
        if (x == 0 || x == 1)
            return 0;
        if (map.containsKey(x))
            return map.get(x);
        long ans = 0;
        for (int i = 2; i < 10; i++)
            if (x >= i) {
                ans += dfs(x / i) + 1; //这道题的难点就是这个地方 这个地方也有优化了求的公式
            }
        map.put(x, ans);
        return map.get(x);
    }
  
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        map.put(new Long(0), new Long(0));
        map.put(new Long(1), new Long(0));
        while (n-- > 0) {
            long l1 = Long.valueOf("" + in.next());
            long l2 = Long.valueOf("" + in.next());
            System.out.println((dfs(l2) - dfs(l1 - 1)) % (1000000007));
  
        }
    }
}

例如dfs(21) 21/(2到9) 也就是方向求2到9各种组合哪些可以乘起来是小于目标数21的 
你们也可以手写2乘于2到9 ......3乘于2到9 .....到9乘于2到9   求出来的数有多少种小于目标数 然后继续将求出来的结果继续乘于2到9 看又有多少种符合条件 
一开始思路是递归 但是存在重复子问题(搜索没有记忆)后面加了记忆省了大量的计算 不出现超时
递归(超时)for(int i = 2 ; i < 10 ; i++){
                            temp *= i;//会产生大量的重复运算 所以解决这个方法采用 记忆
                           if( l<=temp <= r)
                                       ans++;
}
里面还有要注意的是 大部分奇数(实际上是质数)所对应的符合2到9组合的式子是(奇数-1)所对应的值
如 dfs(11) = dfs(10)

原文地址:https://www.cnblogs.com/cznczai/p/11150000.html