解法一:动态规划

dp[i] 表示完成前 i 个数的分隔得到的最大值。有以下状态转移方程:
1043. 分隔数组以得到最大和 - 图1
其中,1043. 分隔数组以得到最大和 - 图2表示原数组下标闭区间 [i,j] 之间的最大值。

  1. class Solution {
  2. public int maxSumAfterPartitioning(int[] arr, int k) {
  3. final int n = arr.length;
  4. // 下标从1开始
  5. // maxVal[i][j]表示下标范围[i, j]之间的最大值
  6. int[][] maxVal = new int[n + 1][n + 1];
  7. for (int i = n; i >= 1; --i) {
  8. maxVal[i][i] = arr[i - 1];
  9. for (int j = i + 1; j <= n; ++j) {
  10. maxVal[i][j] = Math.max(maxVal[i][j - 1], arr[j - 1]);
  11. }
  12. }
  13. // dp[i]表示完成前i个数的分隔得到的最大值
  14. int[] dp = new int[n + 1];
  15. dp[0] = 0;
  16. dp[1] = arr[0];
  17. for (int i = 2; i <= n; ++i) {
  18. dp[i] = Integer.MIN_VALUE;
  19. // 防止下标越界
  20. for (int len = 1; len <= Math.min(i, k); ++len) {
  21. dp[i] = Math.max(dp[i], dp[i - len] + len * maxVal[i - len + 1][i]);
  22. }
  23. }
  24. return dp[n];
  25. }
  26. }