leetcode 1140. Stone Game II 的解法(动态规划标准例题)

题目是:

亚历克斯和李继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]。游戏以谁手中的石子最多来决出胜负。
亚历克斯和李轮流进行,亚历克斯先开始。最初,M = 1。
在每个玩家的回合中,该玩家可以拿走剩下的 前 X 堆的所有石子,其中 1 <= X <= 2M。然后,令 M = max(M, X)。
游戏一直持续到所有石子都被拿走。
假设亚历克斯和李都发挥出最佳水平,返回亚历克斯可以得到的最大数量的石头。

粗略思路:

(1)求最大值,采用动态规划可减少重复计算;

(2)亚历克斯和李均表现为最佳水平,即采用同一策略进行游戏,所以动态规划数组唯一。

详细思路:

(1)选取结果受M和当前的坐标i 影响,所以是动态规划的数据是二维数组;

(2)剩下的石头如果小于2M,可以把剩下的所有石头拿走,可作为动态规划的起始条件;

(3)当前可取的石子为,剩下的所有石头 - 上一次取走的石头,求当前可取石头的最大值,所以递归式为

          

dp[i][j]=max(dp[i][j],resum[i]-dp[i+x][max(j,x)]);

其中resum[i]为剩下的所有石头,上一次取走的石头dp[i+x][max(j,x)],x为这次取的石头堆数,max(j,x)即M = max(M, X)。

代码如下:

class Solution {
public:
    int stoneGameII(vector& piles) {
        int n=piles.size();
        //设置二维动态规划数组,分别式当前回合的起始坐标和M
        vector> dp(n,vector(n,0));
        //求剩下的所有石头总和
        vector resum(n,0);
        int sum=0;
        for(int i=n-1;i>=0;i--)
        {
            sum+=piles[i];
            resum[i]=sum;
        }
        //初始化动态规划初始条件,剩下的石头如果小于2M,可以把剩下的所有石头拿走
        for(int i=0;i=n)
                {
                    dp[i][j]=resum[i];
                }
            }
        }
        //递归
        for(int i=n-1;i>=0;i--)
        {
            for(int j=n-1;j>=0;j--)
            {
                for(int x=1;x<=2*j && i+x

 

你可能感兴趣的:(c++)