Question:
思路:
这个题我乍一看就是用dp, 分段取. 但问题就是用dp就得三维, 因为还有一条k bags的条件. 所以一定会超时. 这个题的解法就真的genuis,
他这个本质上就是要找几个interval 然后这个interval要先找到边界sum最大的. 再找到边界sum 最小的.
所以这种题, 如果我们把它用数学展开来表示. 我们把array 分成 k 份可以写成
arr[] -> [0, m1], [m1+1, m2], [m2 +1, m3]…[mk-1 + 1, k]
再简化一下可以写成
arr[0] + arr[m1] + arr[m1+1] + arr[m2] + arr[m2+1] + arr[m3] + … arr[mk-1 + 1] + arr[last]
如果我们把相邻的几个数字都写在一起就变成
arr[0] + (arr[m1] + arr[m1+1]) + (arr[m2] + arr[m2+1]) + (arr[m3] + … arr[mk-1 + 1]) + arr[last]
这就是我们要找的 score.
假设这个是max.的 那么和min的diff. 就是相当于中间那一大块.
let m1,m2,m3,… represent max score的interval
mm1, mm2, mm3 represent min score的interval.
diff = arr[0] + (arr[m1] + arr[m1+1]) + (arr[m2] + arr[m2+1]) + (arr[m3] + … arr[mk-1 + 1]) + arr[last] - arr[0] - (arr[mm1] + arr[mm1+1]) + (arr[mm2] + arr[mm2+1]) + (arr[mm3] + … arr[mmk-1 + 1]) - arr[last],
现在来看这道题变成了什么, 不就是找出来最大的k-1个相邻的sum - 最小的k-1个相邻sum. 因为arr[0]和arr[last] 肯定max score和 min score里面的bags都有选, 所以可以直接抵消. 然后这个组合可以算成1对pair, 所以再找k-1个 pair (从0 到 n -1)
那么就可以priorityQueue把所有挨着的pair的score按顺序排列.
接着取k-1个就行了
class Solution {
public long putMarbles(int[] weights, int k) {
int n = weights.length - 1;
// calculate all adjacents sum, why? see CSDN
long allAdjacents[] = new long[n], res = 0;
for (int i = 0; i < allAdjacents.length; i++) {
allAdjacents[i] = weights[i] + weights[i + 1];
}
Arrays.sort(allAdjacents);
for (int i = 0; i < k - 1; i++) {
res += allAdjacents[n - 1 - i] - allAdjacents[i];
}
return res;
}
}