「数字三角形最大和A一递归」
题目描述
在下面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。
只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为 0 - 99
输入格式:
5 //表示三角形的行数 接下来输入三角形
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
要求输出最大和
代码案例解析
import java.util.Arrays;
import java.util.Scanner;
public class 数字三角形最大和A一递归 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in) ;
int n = input.nextInt() ;
int [][] arr = new int [n][] ;
for(int i=0; i<n; i++){ //为二维数组分配空间
arr[i] = new int[i+1] ;
}
for(int i=0; i<n; i++){
for(int j=0; j<i+1; j++){
arr[i][j] = input.nextInt() ;
}
}
// 打印二维数组
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr[i]));
}
// 进行递归计算
System.out.println(max1(arr,0,0));
}
public static int max1(int [][] arr, int i, int j){
int rowIndex = arr.length ;
if(i == rowIndex - 1){
return arr[i][j] ;
} else{ //当前数字+max(左下路径,右下路径)
return arr[i][j] + Math.max(max1(arr,i+1, j), max1(arr, i+1, j+1)) ;
}
}
}
「数字三角形最大和B之一维数组动规逆推」
代码案例解析
import java.util.Scanner;
public class 数字三角形最大和B一一维动规逆推 {
public static void main(String[] args) {
// 初始化输入的二维数组
Scanner in = new Scanner(System.in);
int rowSize = in.nextInt();
int[][] arr = new int[rowSize][];
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i+1];
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i + 1; j++) {
arr[i][j] = in.nextInt();
}
}
diTuiArr(arr);
}
/**
* 从下而上递推解法
* @param arr
*/
static void diTuiArr(int[][] arr){
// 定义存储的一维数组
int[] newArr = new int[arr[arr.length-1].length];
for (int i = 0; i < newArr.length; i++) {
newArr[i] = arr[arr.length-1][i];
}
// 从倒数第二行开始逆推
for (int i = arr.length-2; i >=0; i--) {
for (int j = 0; j <= i; j++) {
newArr[j] = Math.max(newArr[j],newArr[j+1])+arr[i][j];
}
}
System.out.println(newArr[0]);
}
}
「数字三角形最大和C之一维数组递归规划」
代码案例解析
import java.util.Arrays;
import java.util.Scanner;
public class 数字三角形最大和C一一维递归规划 {
static int arr[][];
static int newArr[][];
public static void main(String[] args) {
// 初始化输入的二维数组
Scanner in = new Scanner(System.in);
int rowSize = in.nextInt();
arr = new int[rowSize][];
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i+1];
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i + 1; j++) {
arr[i][j] = in.nextInt();
}
}
int colSize = arr[rowSize-1].length;
// 新建一个同大小数组
newArr = new int[rowSize][colSize];
for (int i = 0; i < newArr.length; i++) {
for (int j = 0; j < newArr[i].length; j++) {
newArr[i][j] = -1;
}
}
System.out.println(diGuiArr(0,0));
}
static int diGuiArr(int n,int m){
if( newArr[n][m] != -1 ) {
return newArr[n][m];
}
if(n==arr.length-1){
newArr[n][m] = arr[n][m];
} else{
int x = diGuiArr(n+1,m);
int y = diGuiArr(n+1,m+1);
newArr[n][m] = Math.max(x,y)+ arr[n][m];
}
return newArr[n][m];
}
static void printArr(int[][] arr){
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr[i]));
}
}
}
「数字三角形最大和D之二维动规顺推」
代码案例解析
import java.util.Scanner;
public class 数字三角形最大和D一二维动规顺推 {
/**
* 题目描述
* 在下面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。
* 只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为 0 - 99
*
* 输入格式:
*
* 5 //表示三角形的行数 接下来输入三角形
*
* 7 7
* 3 8 3 8
* 8 1 0 8 1 0
* 2 7 4 4 2 7 4 4
* 4 5 2 6 5 4 5 2 6 5
*
* 要求输出最大和
* @param args
*/
public static void main(String[] args) {
// 初始化输入的二维数组
Scanner in = new Scanner(System.in);
int rowSize = in.nextInt();
int[][] arr = new int[rowSize][];
for (int i = 0; i < arr.length; i++) {
arr[i] = new int[i+1];
}
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i + 1; j++) {
arr[i][j] = in.nextInt();
}
}
// 初始化最左边
for (int i = 1; i < rowSize; i++) {
arr[i][0] = arr[i][0] + arr[i-1][0];
}
// 初始化最右边
for (int i = 1; i < rowSize; i++) {
arr[i][i] = arr[i][i] + arr[i-1][i-1];
}
PrintArrsTwoUtils.printArr(arr);
// 循环往下最大值[i][j] = max([i][j-1],[i-1][j-1])
for (int i = 2; i < rowSize; i++) {
for (int j = 1; j < i; j++) {
arr[i][j] = Math.max(arr[i-1][j],arr[i-1][j-1])+arr[i][j];
PrintArrsTwoUtils.printArr(arr);
}
}
int max = Integer.MIN_VALUE;
for (int i = 0; i < rowSize; i++) {
max = Math.max(arr[rowSize-1][i],max);
}
System.out.println(max);
}
// [7]
// [10, 15]
// [18, 16, 15]
// [20, 25, 20, 19]
// [24, 30, 27, 26, 24]
}
「整数拆分A一递归」
题目描述
给定一个正整数,我们可以定义出下面的公式:
N=a[1]+a[2]+a[3]+…+a[m];
a[i]>0,1<=m<=N;
对于一个正整数,求解满足上面公式的所有算式组合,如,对于整数 4 :
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
所以上面的结果是 5 。
注意:对于 “4 = 3 + 1” 和 “4 = 1 + 3” ,这两处算式实际上是同一个组合!
样例
输入样例
4
10
20
输出样例
5
42
627
代码案例解析
import java.util.Scanner;
public class 整数拆分A一递归 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
System.out.println(method(num,num));
}
/**
* 数字n的m划分
* @param n 需要划分的数字
* @param max 划分最大数
* @return
*/
static int method(int n, int max) {
if(n == 1 || max == 1) {
return 1;
}
if(n < max) {
return method(n, n);
}
if(n == max) {
return 1 + method(n, n - 1);
} else {
return method(n - max, max) + method(n, max - 1);
}
}
}
「整数拆分B一动态数组」
代码案例解析
import java.util.Scanner;
public class 整数拆分B一动态数组 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()){
int num = in.nextInt();
System.out.println(method(num,num));
}
}
static long method(int n, int k){
long[][] dp = new long[n+1][k+1];
for(int i=1;i<=n;i++) {
for(int j=1;j<=k;j++) {
if(i==1||j==1){
dp[i][j]=1;
} else if(i==j){
dp[i][j]=1+dp[i][j-1];
} else if(i<j) {
dp[i][j]=dp[i][i];
} else if(i>j){
dp[i][j]=dp[i-j][j]+dp[i][j-1];
}
}
}
return dp[n][k];
}
}
「整数拆分C之一维数组解法」
代码案例解析
import java.util.Scanner;
public class 整数拆分C一一维数组解法 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()){
int num = in.nextInt();
System.out.println(combinationCount(num));
}
}
public static int combinationCount(int N) {
int[] dp = new int[N + 1];
for (int i = 0; i <= N; i++) {
dp[i] = 1; // 初始化,每个数自身是一种组合方式
}
for (int i = 2; i <= N; i++) {
for (int j = i; j <= N; j++) {
dp[j] = dp[j] + dp[j - i]; // 核心动态规划逻辑,j可以由j-i加上i组合得到,所以dp[j] += dp[j-i]
}
}
return dp[N];
}
}