- Stone Game II
There is a stone game.At the beginning of the game the player picks n piles of stones in a circle.
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
Example 1:
Input:
[1,1,4,4]
Output:18
Explanation:
- Merge second and third piles => [2, 4, 4], score +2
- Merge the first two piles => [6, 4],score +6
- Merge the last two piles => [10], score +10
Example 2:
Input:
[1, 1, 1, 1]
Output:8
Explanation:
- Merge first and second piles => [2, 1, 1], score +2
- Merge the last two piles => [2, 2],score +2
- Merge the last two piles => [4], score +4
解法1:
DP。思路类似Stone Game。但要记得circular buffer的处理。dp[2n][2n], sums[2n]。
代码如下:
class Solution {
public:
/**
* @param A: An integer array
* @return: An integer
*/
int stoneGame2(vector<int> &A) {
int n = A.size();
if (n == 0) return 0;
vector<vector<int>> dp(n * 2, vector<int>(n * 2, 0));
vector<int> sums(n * 2, 0);
sums[0] = A[0];
for (int i = 1; i < n * 2; ++i) {
sums[i] = sums[i - 1] + A[i % n];
}
for (int len = 2; len <= n; ++len) {
for (int i = 0; i + len - 1 < n * 2; ++i) {
dp[i][i + len - 1] = INT_MAX;
int sum = sums[i + len - 1] - sums[i - 1];
for (int k = i; k < i + len - 1; ++k) {
dp[i][i + len - 1] = min(dp[i][i + len - 1], dp[i][k] + dp[k + 1][i + len - 1] + sum);
}
}
}
int result = INT_MAX;
for (int i = 0; i < n; ++i) {
result = min(result, dp[i][i + n - 1]);
}
return result;
}
};