题目来源:http://poj.org/problem?id=1163(北大POJ)
描述:
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.
翻译一下题目大致意思: 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为 0 - 99。
分析:这道题利用动态规划可以很快的解出来。首先利用一个二维数组存储该三角形的所有元素,从底部往上遍历,每一个元素到底部的最大路径值为该元素本身的值加上max(该元素左下元素路径最大值,钙元素右下元素路径最大值)。
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//输入数据
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int[][] a=new int[n][n];
for (int i=0;i<n;i++){
for(int j=0;j<=i;j++){
a[i][j]=scanner.nextInt();
}
}
//只有一行的时候,直接输出该元素
if(n==1){
System.out.println(a[0][0]);
return;
}
for(int i=n-2;i>=0;i--){
for(int j=0;j<=i;j++){
a[i][j]+=Math.max(a[i+1][j],a[i+1][j+1]);
}
}
System.out.println(a[0][0]);
}
}
上面的时间复杂度为O(n^2),再贴一个时间复杂度为O(2^n)的时间超时的代码,引以为鉴:
#include <iostream>
#include <algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int n;
int MaxSum(int i, int j){
if(i==n)
return D[i][j];
int x = MaxSum(i+1,j);
int y = MaxSum(i+1,j+1);
return max(x,y)+D[i][j];
}
int main(){
int i,j;
cin >> n;
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin >> D[i][j];
cout << MaxSum(1,1) << endl;
}
参考博客:https://blog.csdn.net/baidu_28312631/article/details/47418773