2022-05-06:给你一个整数数组 arr,请你将该数组分隔为长度最多为 k 的一些(连续)子数组。分隔完成后,每个子数组的中的所有值都会变为该子数组中的最大值。 返回将数组分隔变换后能够得到的元素最大和。 注意,原数组和分隔后的数组对应顺序应当一致,也就是说,你只能选择分隔数组的位置而不能调整数组中的顺序。 输入:arr = [1,15,7,9,2,5,10], k = 3。 输出:84。 解释: 因为 k=3 可以分隔成 [1,15,7] [9] [2,5,10],结果为 [15,15,15,9,10,10,10],和为 84,是该数组所有分隔变换后元素总和最大的。 若是分隔成 [1] [15,7,9] [2,5,10],结果就是 [1, 15, 15, 15, 10, 10, 10] 但这种分隔方式的元素总和(76)小于上一种。 力扣1043. 分隔数组以得到最大和。

答案2022-05-06:

从左往右的尝试模型。0到i记录dp[i]。 假设k=3,分如下三种情况: 1.i单个一组dp[i]=[i]+dp[i-1]。 2.i和i-1一组。 3.i和i-1和i-2一组。

代码用rust编写。代码如下:

fn main() {
    let mut arr: Vec<isize> = vec![1, 15, 7, 9, 2, 5, 10];
    let k: isize = 3;
    let answer = max_sum_after_partitioning2(&mut arr, k);
    println!("answer = {}", answer);
}

fn max_sum_after_partitioning2(arr: &mut Vec<isize>, k: isize) -> isize {
    if arr.len() == 0 {
        return 0;
    }
    let n = arr.len() as isize;
    let mut dp: Vec<isize> = vec![];
    for _i in 0..n {
        dp.push(0);
    }
    dp[0] = arr[0];
    for i in 1..n {
        dp[i as usize] = arr[i as usize] + dp[(i - 1) as usize];
        let mut max = arr[i as usize];
        let mut j = i - 1;

        while j >= 0 && (i - j + 1) <= k {
            max = get_max(max, arr[j as usize]);
            dp[i as usize] = get_max(
                dp[i as usize],
                max * (i - j + 1) + if j - 1 >= 0 { dp[(j - 1) as usize] } else { 0 },
            );
            j -= 1;
        }
    }
    return dp[(n - 1) as usize];
}

fn get_max(a: isize, b: isize) -> isize {
    if a > b {
        a
    } else {
        b
    }
}

执行结果如下:

在这里插入图片描述


左神java代码