合并石子问题

合并石子

合并石子 标准版

在一个操场上一排地摆放着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];
}

合并石子 每次合成多堆

  1. 合并石头的最低成本
    已解答
    困难
    相关标签
    相关企业
    有 n 堆石头排成一排,第 i 堆中有 stones[i] 块石头。

每次 移动 需要将 连续的 k 堆石头合并为一堆,而这次移动的成本为这 k 堆中石头的总数。

返回把所有石头合并成一堆的最低成本。如果无法合并成一堆,返回 -1 。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值