前言
刷一题更一题
工具类
下文可能出现PrintArrsTwoUtils.printArr();方法。此为打印二维数组方法,可以删除或注释掉。也可以导入执行,不影响结果,只会打印控制台,可用于打断点分析执行。
import java.util.Arrays;
/**
* 打印二维数组方法
*/
public class PrintArrsTwoUtils {
static void printArr(int[][] arr){
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr[i]));
}
System.out.println("————————————————————————");
}
static void printArr(boolean[][] arr){
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr[i]));
}
System.out.println("————————————————————————");
}
static void printArr(String[][] arr){
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr[i]));
}
System.out.println("————————————————————————");
}
}
「动态规划一青蛙跳台阶」
问题描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
代码案例解析
import java.util.Scanner;
public class 动态规划一青蛙跳台阶 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
int[] dp = new int[num+1];
dp[0]=0;
dp[1]=1;
dp[2]=2;
for (int i = 3; i <= num; i++) {
dp[i] = dp[i-1]+dp[i-2];
}
System.out.println(dp[num]);
}
}
「动态规划一机器人走网格不同路径」
题目描述
一个机器人位于一个 m x n 网格的左上角 。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角有多少种走法?
结果案例
案例1:32的方格 共3条路径;
案例2:73的方格 共28条路径。
代码案例解析
public class 动态规划一机器人网格不同路径 {
public static void main(String[] args) {
int row = 3;
int clo = 7;
int[][] dp = new int[row][clo];
for (int i = 0; i < row; i++) {
dp[i][0] = 1;
}
for (int i = 0; i < clo; i++) {
dp[0][i] = 1;
}
for (int i = 1; i < row; i++) {
for (int j = 1; j < clo; j++) {
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
System.out.println(dp[row-1][clo-1]);
}
}
「动态规划一二维矩阵最小和路径」
问题描述
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
举例
输入:
arr = [
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释
因为路径 1→3→1→1→1 的总和最小。
代码案例解析
import java.util.Scanner;
public class 动态规划一二维矩阵最小和路径 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int row = in.nextInt();
int clo = in.nextInt();
int[][] arr = new int[row][clo];
for (int i = 0; i < row; i++) {
for (int j = 0; j < clo; j++) {
arr[i][j] = in.nextInt();
}
}
// 最右侧列只能往下,则可以确定固定累加值
for (int i = row-2; i >=0; i--) {
arr[i][clo-1] = arr[i][clo-1]+arr[i+1][clo-1];
}
// 最下侧行只能往右,则可以确定固定累加值
for (int i = clo-2; i >=0; i--) {
arr[row-1][i] = arr[row-1][i]+arr[row-1][i+1];
}
// 由右下往左上推算最小路径和 i,j为索引
for (int i = row-2; i >=0; i--) {
for (int j = clo-2; j >=0; j--) {
arr[i][j] = arr[i][j]+Math.min(arr[i+1][j],arr[i][j+1]);
}
}
System.out.println(arr[0][0]);
}
}
「动态规划一01背包」
题目描述
N件物品和容量为V的背包,每个物品只能使用一次。
第i物品有体积Vi和价值Wi
输入描述
求解哪些物品装入背包,总体积不超过背包,且总价值最大。
输入第一行N V,表示N个物品和背包体积V
加下来有N行,每行两个整数vi,wi分别表示第i件的体积和价值。
输入样例
4 5
1 2
2 4
3 4
4 5
输入样例
8
代码案例解析
import java.util.Scanner;
public class 动态规划一01背包 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt(); // 物品数量
int bulk = in.nextInt(); // 背包总体积
int[][] goods = new int[size+1][2];
// 初始化物品信息二维数组
for (int i = 1; i <= size; i++) {
goods[i][0] = in.nextInt();// 体积
goods[i][1] = in.nextInt();// 价值
}
int[][] dp = new int[size+1][bulk+1]; // 用size个物品,装bulk体积的包,的最大价值dp[][]
// 当size为0时,不论体积多大背包的价值为0
for (int i = 0; i <= bulk; i++) {
dp[0][i] = 0;
}
// 当背包容积为0时,放不下体积>0的所有物品,所以价值一定为0
for (int i = 0; i <= size; i++) {
dp[i][0] = 0;
}
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= bulk; j++) {
if (goods[i][0]>j){ // 如果物品体积大于背包,则不放入
dp[i][j] = dp[i-1][j];
}else { // 如果体积小于等于,则可选择放或不放,放的话(放入之后,比对的是,还用当前0~i种物品装j重量的最大可能:之前一定计算过。并非只用第i种来填满剩余j)dp[i-1][j]
int i1 = dp[i - 1][j];
int i2 = dp[i - 1][j - goods[i - 1][0]];
int i3 = goods[i - 1][1];
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-goods[i][0]]+goods[i][1]);
}
}
}
System.out.println(dp[size][bulk]);
}
}
「动态规划一完全背包」
题目描述
有N种物品和一个容量为V的背包,每种物品都有无限件可用(这也是与01背包的区别)。
第i种物品的体积是Vi,价值是Wi。求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。
题目描述
输入第一行N和V,表示N种物品和背包体积V
加下来有N行,每行两个整数vi,wi分别表示第i种的体积和价值。
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例
10
代码案例解析
import java.util.Scanner;
public class 动态规划一完全背包 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt(); // 物品数量
int bulk = in.nextInt(); // 背包总体积
int[][] goods = new int[size+1][2];
// 初始化物品信息二维数组
for (int i = 1; i <= size; i++) {
goods[i][0] = in.nextInt();// 体积
goods[i][1] = in.nextInt();// 价值
}
int[][] dp = new int[size+1][bulk+1]; // 用size个物品,装bulk体积的包,的最大价值dp[][]
// 当size为0时,不论体积多大背包的价值为0
for (int i = 0; i <= bulk; i++) {
dp[0][i] = 0;
}
// 当背包容积为0时,放不下体积>0的所有物品,所以价值一定为0
for (int i = 0; i <= size; i++) {
dp[i][0] = 0;
}
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= bulk; j++) {
if (goods[i][0]>j){ // 如果物品体积大于背包,则不放入
dp[i][j] = dp[i-1][j];
}else { // 如果体积小于等于,则可选择放或不放,放的话
dp[i][j] = Math.max(dp[i-1][j],dp[i][j-goods[i][0]]+goods[i][1]);
}
}
}
System.out.println(dp[size][bulk]);
}
}
「动态规划一多重背包」
题目描述
有N种物品和一个容量为V的背包,每种物品都有都有S个。
第i种物品的体积是Vi,价值是Wi,最多有Si个。
输入描述
求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大。
输入第一行N V,表示N种物品和背包体积V
加下来有N行,每行两个整数vi,wi分别表示第i种的体积和价值。
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例
10
代码案例解析
import java.util.Scanner;
public class 动态规划一多重背包 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int size = in.nextInt(); // 物品数量
int bulk = in.nextInt(); // 背包总体积
int[][] goods = new int[size+1][3];
// 初始化物品信息二维数组
int count = 0;// 商品总数,用于初始化所有商品
for (int i = 1; i <= size; i++) {
goods[i][0] = in.nextInt();// 体积
goods[i][1] = in.nextInt();// 价值
goods[i][2] = in.nextInt();// 数量
count += goods[i][2];
}
// 平铺可用于装包的物品
int[][] allGoods = new int[count+1][2];
int allIndex = 1;
for (int i = 1; i <= size; i++) {
for (int j = 0; j < goods[i][2]; j++) {
allGoods[allIndex][0] = goods[i][0];
allGoods[allIndex][1] = goods[i][1];
allIndex++;
}
}
int[][] dp = new int[count+1][bulk+1]; // 用平铺后的count种物品,装bulk体积的包,的最大价值dp[][]
// 当size为0时,不论体积多大背包的价值为0
for (int i = 0; i <= bulk; i++) {
dp[0][i] = 0;
}
// 当背包容积为0时,放不下体积>0的所有物品,所以价值一定为0
for (int i = 0; i <= count; i++) {
dp[i][0] = 0;
}
for (int i = 1; i <= count; i++) {
for (int j = 1; j <= bulk; j++) {
if (allGoods[i][0]>j){ // 如果物品体积大于背包,则不放入
dp[i][j] = dp[i-1][j];
}else { // 如果体积小于等于,则可选择放或不放,放的话
dp[i][j] = Math.max(dp[i-1][j],dp[i][j-allGoods[i][0]]+allGoods[i][1]);
}
}
}
System.out.println(dp[count][bulk]);
}
}