一开始解不出来 看了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)