Stone Game

题目:

There is a stone game.At the beginning of the game the player picks n piles of stones in a line.

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

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

You are to determine the minimum of the total score.

Example: For [4, 1, 1, 4], in the best solution, the total score is 18:

1. Merge second and third piles => [4, 2, 4], score +2
2. Merge the first two piles => [6, 4],score +6
3. Merge the last two piles => [10], score +10

分析:

这是第一道区间型的动态规划,所谓区间型,就是多了个概念,你要考虑所有区间的可能,并且选出其中的最大值和最小值。这种动态规划的题目,没见过的时候很难在45min内答出来,真的不容易。

state: dp[i][j],merge从i到j的石子的时候能得到的最小score.
这道题目需要sum数组的辅助,因为实际上每次merge的时候,是value + cost,而不是仅仅记录cost

解法:

class Solution {
public:
    /**
     * @param A an integer array
     * @return an integer
     */
    int stoneGame(vector<int>& A) {
        // Write your code here
        int n = A.size();
        if (n == 0 || n == 1) {
            return 0;
        }
        if (n == 2) {
            return A[0] + A[1];
        }
        vector<int> sum(n + 1, 0);
        for (int i = 1; i <= n; i++) {
            sum[i] = sum[i - 1] + A[i - 1];
        }
        vector<vector<int> > dp(n, vector<int>(n, 0) );
        for (int i = 0; i < n; i++) {
            dp[i][i] = 0;
        }
        for (int span = 1; span < n; span++) {
            for (int i = 0, j = i + span; i < n && j < n; i++, j++) {
                int minVal = INT_MAX;
                for (int k = i; k < j; k++) {
                    int firstHalf = dp[i][k];
                    int secondHalf = dp[k + 1][j];
                    int currSum = sum[j + 1] - sum[i];
                    minVal = min(minVal, firstHalf + secondHalf + currSum);
                }
                dp[i][j] = minVal;
            }
        }
        return dp[0][n - 1];
    }
};

results matching ""

    No results matching ""