LeetCode877. 石子游戲(博弈+動態規劃)

題目鏈接Leetcode877

在這裏插入圖片描述


思路
dp[i][j]表示從下標i到j中去左邊和取右邊的最大值
轉移方程:dp[i][j]=max(dp[i+1][j]+val[i], dp[i][j-1]+val[j]);
顯然,根據這個狀態的設定有dp[i][i]=val[i];除此之外,i<=j


記憶化搜索:

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        int d[500][500]={0};
        return dp(0, piles.size()-1, d, piles)>0;
    }

    int dp(unsigned int l, unsigned int r, int d[][500], vector<int>& piles) {
        if(d[l][r]) return d[l][r];
        if(l==r) return d[l][r]=piles[l];
        return d[l][r]=max(piles[l]+dp(l+1, r, d, piles), piles[r]+dp(l, r-1, d, piles));
    }
};

迭代:

class Solution {
public:
    bool stoneGame(vector<int>& piles) {
        //關於遞推的順序由於要滿足子問題先解決,所以要讓區間長度由小到大遞推
        //所以i和j的方向要相反
        int dp[500][500], n=piles.size();
        for(int i=0; i<n; i++) dp[i][i]=piles[i];
        for(int i=n-2; i>=0; i--)
            for(int j=i+1; j<n; j++)
                dp[i][j]=max(piles[i]+dp[i+1][j], piles[j]+dp[i][j-1]);
        return dp[0][n-1]>0;
    }
};

規律:
發現這個設置的狀態無論如何都會滿足最大值大於0,所以這個問題先手必勝,返回一個true也能解決問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章