合并石子
合并石子 标准版
在一个操场上一排地摆放着N堆石子。现要将石子有次序地合并成一堆。规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。 计算出将N堆石子合并成一堆的最小得分。
这道题目就是标准的区间dp
定义dp[i][j]表示(i,j)合成为一堆的得分是多少
显而易见,求的结果就是dp[0][n-1] 状态初值是dp[i][i]=0
那么转移方程是什么?
在将(i,j)这个大区间变成小区间的过程不是一蹴而就的,显然可以划分为若干子任务。
实际上就是在这个区间寻找一个中间点k,尝试dp[i][k] + dp[k+1][j]
所以dp[i][j] = Math.min(dp[i][k],dp[k+1][j] + sum[r] - sum[l-1])
这里的sum是前缀和数组,因为本质上合并(i,j)的石子都要加上一个这区间石子总数的分数,这是必不可少的。
最后返回dp[0][n-1]
注意前缀和的下标,以及dp数组的初始化最大值
public int mergeStones(int[] stones) {
int n = stones.length;
int[][] dp = new int[n][n];
int[] sum = new int[n+1];
for(int i=1;i<=n;i++){
sum[i] = sum[i-1] + stones[i-1];
}
for(int len = 2;len<=n;len++){
for(int l = 0;l+len-1<n;l++){
int r = l + len - 1;
dp[l][r] = Integer.MAX_VALUE;
for(int kk=l;kk<r;kk++){
dp[l][r] = Math.min(dp[l][r], dp[l][kk] + dp[kk+1][r] + sum[r+1] - sum[l]);
}
}
}
return dp[0][n-1];
}
合并石子 每次合成多堆
- 合并石头的最低成本
已解答
困难
相关标签
相关企业
有 n 堆石头排成一排,第 i 堆中有 stones[i] 块石头。
每次 移动 需要将 连续的 k 堆石头合并为一堆,而这次移动的成本为这 k 堆中石头的总数。
返回把所有石头合并成一堆的最低成本。如果无法合并成一堆,返回 -1 。