lintcode Guess Number Game II
阿新 • • 發佈:2019-02-20
動態規劃解析:
解法一: 記憶化搜尋
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];
}