这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战
1959. K 次调整数组大小浪费的最小总空间
思路分析
由题意可知,调整n次数组的浪费空间一定小于等于调整n-1次数组的浪费空间,从示例1中我们可以看到,一段数组经过一次调整后,浪费空间其实就是最大值乘长度-sum(数组)。我们可以将一个数组k次调整看为k段数组一次调整。
这样就很明显的注意到这道题可以使用动态规划完成了,因为这道题变为了将数组分为k段的过程(由于分k段一定比k-1段强,而且这里如果不考虑顺序的话,所有的k段可能都可以理解为从前往后分出来的)。
我们用dp[i][j]表示从0到i的数组分为了j段的浪费空间,那么容易得到状态转移方程为:
dp[i][j] = min(dp[i - k][j - 1] + max * k - sum(i-k,k));
其中k可能为0到i- 1的任意值。
int dp[nums.size()][k + 1];
for (int i = 0 ; i < nums.size(); i ++){
for(int j = 0; j < k + 1; j ++){
if (j == 0)dp[i][j] = arr[0][i];
else{
dp[i][j] = INT_MAX;
for(int t = 0; t < i; t ++){
dp[i][j] = min(dp[i][j], dp[t][j - 1] + arr[t + 1][i]);
}
if (dp[i][j] == INT_MAX)dp[i][j] = 0;
}
}
}
这里需要简单的说下,arr[i][j]作为一个子序列和,可以轻松通过求个前缀和再两次for循环得到,也可以写三次for循环。
当j == 0时,其实就是只能设置一次数组初始值,这个的计算其实示例一已经写的很清楚了,也恰好就是arr[0][i]