1. 程式人生 > >lintcode Guess Number Game II

lintcode Guess Number Game II

動態規劃解析:

解法一: 記憶化搜尋

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];
}