#1037 : 数字三角形

  #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);
    }

}

你可能感兴趣的:(算法,动态规划)