区间型

详解

https://mnmunknown.gitbooks.io/algorithm-notes/content/625,_dong_tai_gui_hua_ff0c_qu_jian_lei_dp.html

Stone Game

There is a stone game.At the beginning of the game the player picksnpiles of stones in a line.

The goal is to merge the stones in one pile observing the following rules:

  1. At each step of the game,the player can merge two adjacent piles to a new pile.
  2. The score is the number of stones in the new pile.

You are to determine the minimum of the total score.

思路:

典型的区间型问题,需要借助 prefix sum来计算i到j的merge cost。dp定义也是很典型的从i到j的合并最少cost。

代码实现就是三层for 循环。 第一层是length,这是subproblem的规模,我们需要从小到大来计算。第二层是起始位置,第三层是终点位置。

public int stoneGame(int[] A) {
        // Write your code here
        if (A == null || A.length == 0)
            return 0;

        int n = A.length;

        int[] sum = new int[n+1];
        for (int i = 1; i <= n; i++) {
            sum[i] = sum[i-1] + A[i-1];
        }

        int[][] dp = new int[n+1][n+1];
        for (int i = 1; i <= n; i++) {
            dp[i][i] = 0; 
        }

        for (int i = 2; i <= n; i++) { //length
            for (int j = 1; j+i-1 <= n; j++) { //start
                int k = j + i -1;
                dp[j][k] = Integer.MAX_VALUE;
                for (int l = j; l < k; l++) {
                    dp[j][k] = Math.min(dp[j][k], dp[j][l] + dp[l+1][k] + sum[k] - sum[j-1]);
                }
            }
        }

        return dp[1][n];
    }

Stone Game II

将上一道题延伸成环。因此需要double length for dp。最后需要遍历一遍得到最小值。

public int stoneGame2(int[] A) {
        // Write your code here
        if (A == null || A.length == 0)
            return 0;

        int n = A.length;

        // cal sum to get sum from i to j by sum[j] - sum[i-1]
        int[] sum = new int[2*n+1];
        for (int i = 1; i <= 2 * n; i++) {
            sum[i] = sum[i-1] + A[(i-1) % n];
        }

        // initialization cost to merge self is 0
        int[][] dp = new int[2*n + 1][2 * n + 1];
        for (int i = 1; i <= 2*n; i++) {
            dp[i][i] = 0;
        }

        for (int i = 2; i <= n; i++) { // length (calced when length == 1)
            for (int j = 1;  j + i -1 <= 2 *n; j++) {// start point
                int k = j+ i - 1; // end point
                dp[j][k] = Integer.MAX_VALUE;
                // loop over from start to end
                for (int l = j; l < k; l++) {
                    dp[j][k] = Math.min(dp[j][k], dp[j][l] + dp[l+1][k] + sum[k] - sum[j-1]);
                }
            }
        }

        int ans = Integer.MAX_VALUE;
        // loop over dp result
        for (int i = 1; i <= n; ++i)
            if (dp[i][i + n - 1 ] < ans)
                ans = dp[i][i + n - 1];

        return ans;
    }

Burst Balloons

Givennballoons, indexed from0ton-1. Each balloon is painted with a number on it represented by arraynums. You are asked to burst all the balloons. If the you burst ballooniyou will getnums[left] * nums[i] * nums[right]coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.

Find themaximumcoins you can collect by bursting the balloons wisely.

  • You may imaginenums[-1] = nums[n] = 1. They are not real therefore you can not burst them.
  • 0 ≤n≤ 500, 0 ≤nums[i]≤ 100

思路:

这题和stones非常相似,唯一需要注意的是需要在数组两端加上虚拟的1用来计算第一个元素和最后一个元素。

 public int maxCoins(int[] nums) {
        // Write your code here
        if (nums == null || nums.length == 0)
            return 0;

        int[] A = new int[nums.length+2];
        A[0] = 1;
        A[A.length-1] = 1;
        for (int i = 0; i < nums.length; i++) {
            A[i+1] = nums[i];
        }

        int n = A.length;
        int[][] dp = new int[n][n];
        for (int i = 1; i <= n-2; i++) {
            dp[i][i] = A[i-1] * A[i] * A[i+1];
        }

        for (int len = 2; len <= n-2; ++len) {
            for (int left = 1; left + len - 1 <= n-2; ++left) {
                int right = left + len - 1;
                for (int k = left; k <= right; ++k) {
                    dp[left][right] = Math.max(dp[left][right], A[left - 1] * A[k] * A[right + 1] + dp[left][k - 1] + dp[k + 1][right]);
                }
            }
        }
        return dp[1][n-2];

    }

Scramble String

Copy Books

Copy Books II

Post Office

Matrix Chain Multiplication

reference

results matching ""

    No results matching ""