#1037 : 数字三角形是一道动态规划,需要一个二维数组去存储中间信息。动态规划的理解可以参考笔者另一篇博文hihicoder #1038 : 01背包。上面引用了知乎的回答。
题目中的三点提示:
提示一:盲目贪心不可取,搜索计算太耗时
提示二:记忆深搜逞神威,宽度优先解难题
提示三:总结归纳提公式,减少冗余是真理
这道题贪心算法无法达到全局最优,搜索主要分深度搜索和跨度搜索。普通搜索就是遍历,记忆深搜是保存一些中间结构,然后避免一些不必要的搜索。这已经和动归有些类似,就是都使用了这个问题无后效性的特点。但是记忆深搜应该还是会重复计算子问题,换成记忆宽度优先遍历可以避免重复计算子问题的问题。动态规划的一个特点就是状态转移公式,我的认为是也相当于递推公式,这往往是解决问题的关键。
下面是参考代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sin = new Scanner(System.in);
int numlines = Integer.valueOf(sin.nextInt());
int n = numlines;
sin.nextLine();
int price[][] = new int[numlines][numlines];
int getPrices[][] = new int[numlines][numlines];
while (numlines-- != 0) {
String tmp[] = sin.nextLine().split(" ");
for (int i = 0; i < n - numlines; i++) {
price[n-numlines-1][i] = Integer.valueOf(tmp[i]);
}
}
getPrices[0][0] = price[0][0];
for (int i = 1; i < price.length; i++) {
for (int j = 0; j < price[0].length; j++) {
if (j == 0) {
getPrices[i][j] = getPrices[i-1][j] + price[i][j];
} else if (i == j) {
getPrices[i][j] = getPrices[i-1][j-1] + price[i][j];
} else {
getPrices[i][j] = Math.max(getPrices[i-1][j-1], getPrices[i-1][j]) + price[i][j];
}
}
}
int res = getPrices[n-1][0];
for (int i = 1; i < n; i++) {
if (getPrices[n-1][i] > res) {
res = getPrices[n-1][i];
}
}
System.out.println(res);
}
}