1. 程式人生 > 其它 >Leetcode_1690_石子游戲 Ⅶ_動態規劃

Leetcode_1690_石子游戲 Ⅶ_動態規劃

技術標籤:daily_algorithm動態規劃動態規劃leetcode

12/17

後有詳細解答步驟
class Solution {
    public int stoneGameVII(int[] stones) {
        int n=stones.length;
        //從第一個到第i個,石頭的總數
        int []sum=new int[n];
        sum[0]=stones[0];
        for(int i=1;i<n;i++){
            sum[i]=sum[i-1]+stones[i];
        }
//從第i個到第j個兩者最大的差值 int [][]dp=new int[n][n]; /* dp[x][x]=0; dp[x-1][x-1]=0; dp[x-1][x]=min(stones[x-1],stones[x]); dp[x-2][x]=max(sum[x-1,x]-dp[x-1][x],sum[x-2,x-1]-dp[x-2][x-1]); */ for(int st=n-2;st>=0;st--){ for(int ed=
st+1;ed<n;ed++){ dp[st][ed]=Math.max(-dp[st+1][ed]+sum[ed]-sum[st],-dp[st][ed-1]+sum[ed-1]-(st==0?0:sum[st-1])); } } return dp[0][n-1]; } }

第一步:觀察

觀察到這題無法用貪心完成,需要用動態規劃

第二步:思考轉移的狀態是什麼

我們首先先明確一點,先取的一定比後取的拿的多
最終需要返回的是第0到第n-1個的石子時候,二者的最大差值
我們將其前進一步
很容易發現就兩種轉換方式
要麼取左邊,要麼取右邊

取左邊的價值是獲得第1到第n-1個石子的總和
代價是減少(從1到第n-1個石子時,二者的最大差值)

取右邊的價值是獲得第0到第n-2個石子的總和
取右邊的代價是減少(從第0到第n-2個石子時,二者的最大差值)

寫成公式就是
dp[0][n-1]=max(sum[1,n-1]-dp[1][n-1],sum[0,n-2]-dp[0][n-2]);

第三步:思考轉移的順序

很容易發現我們的公式是從外向內轉移的
也就是我們為了獲取最終dp[0,n-1],
我們必須先獲取內部的dp[1][n-1]與dp[0][n-2],
也就是我們的轉移順序是從內而外
即先算出內部,再慢慢向外部轉移
我們觀察到
當起始點和終止點重合時:dp[x][x]=0;
而當起始點和終止點相差為1時,dp[x-1][x]=min(stones[x-1],stones[x]);
仍滿足轉移方程,並且dp[x][x]的值為int陣列初值,我們不必提前賦值