1.题目描述
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的样例中,从 7 \to 3 \to 8 \to 7 \to 57→3→8→7→5 的路径产生了最大
输入输出样例
输入 #1
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
输出 #1
30
import java.util.Scanner;
public class Main4 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[][] arr = new int[n][n];
int[][] count = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < i + 1; j++) {
arr[i][j] = scanner.nextInt();
}
}
count[0][0] = arr[0][0];
if(n == 1){
System.out.println(count[0][0]);
return;
}
count[1][0] = arr[1][0]+arr[0][0];
count[1][1] = arr[1][1]+arr[0][0];
if(n == 2){
System.out.println(Math.max(count[0][0]+count[1][0],count[1][1]));
return;
}
int sum = Integer.MIN_VALUE;
for (int i = 2; i < n; i++) {
for (int j = 0; j <= i; j++) {
if(j == 0)
count[i][j] = count[i-1][j]+arr[i][j];
else if (j == i)
count[i][j] = count[i-1][j-1]+arr[i][j];
else {
count[i][j] = Math.max(arr[i][j]+count[i-1][j],arr[i][j]+count[i-1][j-1]);
}
}
}
for (int i = 0; i < n; i++) {
sum = Math.max(sum,count[n-1][i]);
}
System.out.println(sum);
}
}
发现这个MLE里面的例子有上万行,我的....
优化后的代码
其实可以从下往上走,在走的时候就已经做了判断大小,不需要之前走完还有继续比较
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();// 数组的行列数
int[][] num = new int[n][n];
for (int i = 0; i < n; i++) {// 输入数组
for (int j = 0; j < i + 1; j++) {
num[i][j] = sc.nextInt();
}
}
System.out.println(dpd(num));
}
public static int dpd(int[][] num) {
int row = num.length;// 定义行数
int line = num[row - 1].length;// 定义列数
int[][] dp = new int[row][line];// 定义dp数组
for (int i = 0; i < line; i++) {// 初始化最后一行
dp[row - 1][i] = num[row - 1][i];
}
for (int i = row - 2; i >= 0; i--) {// 从最后一行向前走 所以i从倒数第二行开始
for (int j = 0; j <= i; j++) {
dp[i][j] = num[i][j] + Math.max(dp[i + 1][j], dp[i + 1][j + 1]);
}
}
return dp[0][0];
}
}
2.题目
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
输入 #1
389 207 155 300 299 170 158 65
输出 #1
6
2
import java.util.Scanner;
public class te {
//动态规划,创建特殊数组
static int[] len, height, count;
static int max1, max2;
public static void dio(int k){
for (int i = 0; i < k; i++) {
len[i] = 1;
count[i] = 1;
//每一次都与前面的数遍历,只取最大值
for (int j = 0; j < i; j++) {
if(height[i] <= height[j]){
len[i] = Math.max(len[i], len[j]+1);
}else{
count[i] = Math.max(count[i], count[j]+1);
}
}//389 207 155 300 299 170 158 65
max1 = Math.max(max1, len[i]);
max2 = Math.max(max2, count[i]);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String arr = sc.nextLine();
String[] a = arr.split(" ");
int n = a.length;
len = new int[n];
count = new int[n];
height = new int[n];
for (int i = 0; i < n; i++) {
height[i] = Integer.parseInt(a[i]);
}
dio(n);
System.out.println(max1);
System.out.println(max2);
}
}