2140. 解决智力问题 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/solving-questions-with-brainpower/
解题思路
解题第一层级:依次从每个问题开始,往下找最大值。例如事例二,从问题0开始,跳过了问题1,然后问题就简化成了从问题3,4,5里面重新选择一个开始。
解题第二层级:假如按照第一层级,会有大量的重复计算。需要把计算过的子问题做一个记录。假如你从问题0,问题1,问题2, 都可以跳到问题3,那问题3之后的子问题的解决是一样的,因此需要记录问题开始的最大值。
解题第三层级:假如你在计算子问题的时候,你需要计算一个最大值。例如,你的问题很多,在计算问题next到末尾的最大值的时候,很可能最大值已经计算过了,因此,对该最大值也做一个记录。
解题代码
public class Solution2140 {
private int n;
private int[][] questions;
private long[] b;
private long[] maxList;//从index到最后这段距离里面,最大值找到了。
public static void main(String[] args) {
int[][] a = {{21, 5}, {92, 3}, {74, 2}, {39, 4}, {58, 2}, {5, 5}, {49, 4}, {65, 3}};
System.out.println(new Solution2140().mostPoints(a));
}
public long mostPoints(int[][] questions) {
this.n = questions.length;
this.questions = questions;
this.maxList = new long[n];
this.b = new long[n];
long res = 0;
for (int i = 0; i < n; i++) {
res = Math.max(dfs(i), res);
}
return res;
}
private long dfs(int start) {
if (start >= n) {
return 0;
}
if (b[start] != 0) {
return b[start];
}
int point = questions[start][0];
int next = questions[start][1] + start + 1;
if (next >= n) {
b[start] = point;
return b[start];
}
long maxB = 0;
for (int i = next; i < n; i++) {
if (maxList[i] == 0) {
long c = dfs(i);
maxB = Math.max(c, maxB);
} else {
maxB = Math.max(maxB, maxList[i]);
break;
}
}
maxList[next] = maxB;
b[start] = maxB + point;
return b[start];
}
}