动态规划解析:
解法一: 记忆化搜索
1. state: dp[i][j] 为 从i 到 j 最少消耗的钱
2. function: dp[i][j] = min(value[k] + max(dp[i][k],dp[k+1][j]))
3. initialize: dp[0..n][0..n] = -1
4. answer: dp[0][n-1]
详细代码: c++
int** dp;
int getMoneyAmountHelper (int low, int high) {
if (low >= high) {
return 0;
}
if (dp[low][high] != -1) {
return dp[low][high];
}
int maxCost = pow(2,31) - 1;
for (int i = low; i <= high; i++){
int left = getMoneyAmountHelper(low,i-1);
int right = getMoneyAmountHelper(i+1, high);
maxCost = min(maxCost, max(left, right));
}
return dp[low][high] = max1;
}
int getMoneyAmount(int n) {
dp = new int*[n];
for(int i = 0; i < n; i++) {
dp[i] = new int[n];
for (int j = 0; j < n; j++) {
dp[i][j] = -1;
}
}
return getMoneyAmountHelper(0,n-1);
}
解法二: 循环
和记忆化搜索的差别在与 要注意初始化顺序
int getMoneyAmount(int n) {
int dp[n][n];
const int INTMAX = pow(2, 31) - 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
dp[i][j] = INTMAX;
}
}
for (int i = 0; i < n; i++) {
dp[i][i] = 0;
}
for (int width = 1; width < n; width++) {
for (int i = 0, j = i + width; j < n; i++, j++) {
for (int k = i; k <= j; ++k) {
if (k > i && k < j) {
dp[i][j] = min(dp[i][j], k + 1 +
max(dp[i][k - 1], dp[k + 1][j]));
} else if (k == i) {
dp[i][j] = min(dp[i][j], k + 1 + dp[i + 1][j]);
} else {
dp[i][j] =min(dp[i][j], k + 1 + dp[i][j-1]);
}
}
}
}
return dp[0][n - 1];
}