1. 合并金币问题
动态规划,dp[j][i] 表示合并第j个到第i个金币的总花费(j>=i 从前往后的顺序合并)
j==i 时候 dp=0 就一个金币,无需合并 ;
i==j+1 时候 dp=相邻两个金币和 相邻;
其他情况 dp[j][i] = min{ dp[j][k] + dp[k+1][i] + sum } j<=k<i ,分别合并此区间内左区间dp[j][k],右区间 dp[k+1][i] ,最后合并左右区间还需花费 金币j到i的和 sum
import java.util.Scanner; /** * @author zzm * @data 2020/4/17 21:18 * 有 N 堆金币排成一排,第 i 堆中有 C[i] 块金币。每次合并都会将相邻的两堆金币合并为一堆,成本为这两堆金币块数之和。 * 经过N-1次合并,最终将所有金币合并为一堆。请找出将金币合并为一堆的最低成本。 * 其中,1 <= N <= 30,1 <= C[i] <= 100 * 输入描述: * 第一行输入一个数字 N 表示有 N 堆金币 * 第二行输入 N 个数字表示每堆金币的数量 C[i] * 输出描述: * 输出一个数字 S 表示最小的合并成一堆的成本 */ public class MTmergeCoin { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int len = Integer.parseInt(scanner.nextLine()); String s = scanner.nextLine(); String[] split = s.split(" "); int[] coins = new int[len]; int[] sum = new int[len + 1]; for (int i = 0; i < len; i++) { coins[i] = Integer.parseInt(split[i]); sum[i + 1] = coins[i] + sum[i]; } int[][] dp = new int[len + 1][len + 1]; for (int i = 1; i <= len; i++) { for (int j = i; j > 0; j--) { if (i == j) dp[i][j] = 0; else if (j == i - 1) dp[j][i] = coins[i - 1] + coins[i - 2]; else { dp[j][i] = Integer.MAX_VALUE; for (int k = j; k < i; k++) { dp[j][i] = Math.min(dp[j][i], dp[j][k] + dp[k + 1][i] + sum[i] - sum[j - 1]); } } } } System.out.println(dp[1][len]); } }