LintCode 476.石子归并

有一个石子归并的游戏。最开始的时候,有n堆石子排成一列,目标是要将所有的石子合并成一堆。合并规则如下:

每一次可以合并相邻位置的两堆石子
每次合并的代价为所合并的两堆石子的重量之和
求出最小的合并代价。

区间型动态规划
dp数组每个点代表合并从序号i到j石子的最小代价
对所有可能的划分区间进行遍历
对左右两个区间进行搜索 dfs
用一个二维数据记录搜索过的区间

public class Solution {
    /**
     * @param A: An integer array
     * @return: An integer
     */
    public int stoneGame(int[] A) {
        if(A == null || A.length == 0)
            return 0;
        int n = A.length;
        int[][] dp = new int[n][n];
        boolean[][] flag = new boolean[n][n];
        int[][] sum = new int[n][n];
        for(int i = 0; i < n; i++){
            sum[i][i] = A[i];
            dp[i][i] = 0;
            for(int j = i + 1; j < n; j++){
                sum[i][j] = sum[i][j-1] + A[j];
            }
        }
        return search(0, n-1, dp, flag, sum);
        
    }
    private int search(int l, int r, int[][] dp, boolean[][] flag, int[][] sum){
        if(flag[l][r] == true)
            return dp[l][r];
        if(l == r){
            flag[l][r] = true;
            return dp[l][r];
        }
        dp[l][r] = Integer.MAX_VALUE;
        for(int k = l; k < r; k++){
            dp[l][r] = Math.min(dp[l][r], search(l, k, dp, flag, sum) + search(k+1, r, dp, flag, sum) + sum[l][r]);
        }
        flag[l][r] = true;
        return dp[l][r];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值