2024.2.3力扣每日一题——石子游戏7

题目来源

力扣每日一题;题序:1690

我的题解

方法一 前缀和+记忆化搜索

假设需要的区间为[i,j]的石头待选择,对于本轮的玩家来说,可以选择最左侧的元素i和最右侧的元素j。假设剩下的元素为[ s i , s i + 1 , . . . , s j s_i,s_{i+1},...,s_j si,si+1,...,sj],并且该轮轮到Bob选择,Bob有两种选择:

  • 假设选择 s i s_i si,则其得很为 ∑ k − i + 1 j \sum_{k-i+1}^j ki+1j,剩下的元素为[ s i + 1 , s i + 2 , . . . , s j s_{i+1},s_{i+2},...,s_j si+1,si+2,...,sj],由于Alice乡努力扩大得分差值,假设Alice在剩余石头序列中的得分与Bob得分最大差值为 f ( i + 1 , j ) f(i+1,j) f(i+1,j),则此时Bob与Alice的得分差值为 ∑ k − i + 1 j − f ( i + 1 , j ) \sum_{k-i+1}^j-f(i+1,j) ki+1jf(i+1,j)
  • 假设选择 s j s_j sj,则其得很为 ∑ k − i j − 1 \sum_{k-i}^{j-1} kij1,剩下的元素为[ s i , s i + 1 , . . . , s j − 1 s_{i},s_{i+1},...,s_{j-1} si,si+1,...,sj1],由于Alice乡努力扩大得分差值,假设Alice在剩余石头序列中的得分与Bob得分最大差值为 f ( i , j − 1 ) f(i,j-1) f(i,j1),则此时Bob与Alice的得分差值为 ∑ k − i j − 1 − f ( i , j − 1 ) \sum_{k-i}^{j-1}-f(i,j-1) kij1f(i,j1)
  • 在序列[ s i , s i + 1 , . . . , s j s_i,s_{i+1},...,s_j si,si+1,...,sj]中,Bob与Alice得分差值的最大值为 f ( i , j ) = m a x ( ∑ k − i + 1 j − f ( i + 1 , j ) , ∑ k − i j − 1 − f ( i , j − 1 ) ) f(i,j)=max(\sum_{k-i+1}^j-f(i+1,j),\sum_{k-i}^{j-1}-f(i,j-1)) f(i,j)=max(ki+1jf(i+1,j),kij1f(i,j1))。所以,最大得分差值=当前玩家所获得的价值-剩余序列中对手与自己的得分差值的最大值。

可以采用自顶向下的记忆化搜索,要求区间[i,j]得分的最大差值为 f ( i , j ) f(i,j) f(i,j),只需要求出区间[i,j-1]和[i+1,j]的最优值即可。

时间复杂度:O( n 2 n^2 n2)。其中,n表示数组的长度。需要分别求每个区间(i,j)的最优子状态,一共就有 n 2 n^2 n2个子状态需要计算。
空间复杂度:O( n 2 n^2 n2)。记忆化搜索的字典需要的空间。

public int stoneGameVII(int[] stones) {
    int n=stones.length;
    int[] preSum=new int[n+1];
    for(int i=0;i<n;i++){
        preSum[i+1]=preSum[i]+stones[i];
    }
    int[][] memo=new int[n][n];
    int left=0,right=n-1;
    return dfs(left,right,preSum,memo);
}
public int dfs(int left,int right,int[] sum,int[][] memo){
    if(left>=right){
        return 0;
    }
    if(memo[left][right]!=0){
        return memo[left][right];
    }
    // 取左边
    int res=Math.max(sum[right+1]-sum[left+1]-dfs(left+1,right,sum,memo),
    // 取右边
            sum[right]-sum[left]-dfs(left,right-1,sum,memo));
    memo[left][right]=res;
    return res;
}
方法二 前缀和+动态规划

也可以使用动态规划的思想来实现。可以先求区间[i,j]得分的最大差值,然后再求区间[i,j-1]和[i+1,j]的最优值,最后得出区间[0,n-1]的最大差值。
转移公式:dp[i][j]=max(sum[j+1]-sum[i+1]-dp[i+1][j],sum[j]-sum[i]-dp[i][j-1])

时间复杂度:O( n 2 n^2 n2)。其中,n表示数组的长度。需要分别求每个区间(i,j)的最优子状态,一共就有 n 2 n^2 n2个子状态需要计算。
空间复杂度:O( n 2 n^2 n2)。动态表需要的空间。

public int stoneGameVII(int[] stones) {
    int n=stones.length;
    int[] preSum=new int[n+1];
    for(int i=0;i<n;i++){
        preSum[i+1]=preSum[i]+stones[i];
    }
    int[][] dp=new int[n][n];
    for(int i=n-2;i>=0;i--){
        for(int j=i+1;j<n;j++){
        //preSum[j+1]-preSum[i+1]表示[i+1,j]的和,preSum[j]-preSum[i]表示[i,j-1]的和
            dp[i][j]=Math.max(preSum[j+1]-preSum[i+1]-dp[i+1][j],preSum[j]-preSum[i]-dp[i][j-1]);
        }
    }
        return dp[0][n-1];
    }

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

相关推荐

  1. 2024.2.3每日——石子游戏7

    2024-03-31 22:24:02       17 阅读
  2. 每日 6/7

    2024-03-31 22:24:02       9 阅读
  3. 2023.12.23每日——移除石子使总数最小

    2024-03-31 22:24:02       40 阅读
  4. 每日 292 Nim游戏

    2024-03-31 22:24:02       27 阅读
  5. 每日 1696跳跃游戏

    2024-03-31 22:24:02       39 阅读
  6. 每日 LCP30.魔塔游戏

    2024-03-31 22:24:02       32 阅读
  7. 2024.2.4每日——Nim游戏

    2024-03-31 22:24:02       18 阅读
  8. 2024.2.1每日——数字游戏

    2024-03-31 22:24:02       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-31 22:24:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-31 22:24:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-31 22:24:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-31 22:24:02       20 阅读

热门阅读

  1. 6 字符串、元组和字典

    2024-03-31 22:24:02       15 阅读
  2. Unity 通过鼠标移动和LineRenderer组件实现画线功能

    2024-03-31 22:24:02       16 阅读
  3. stm32通过串口发送float数据的方法

    2024-03-31 22:24:02       15 阅读
  4. 求整数各个数位上的数字之和 C语言

    2024-03-31 22:24:02       15 阅读
  5. C++ //CCF-CSP计算机软件能力认证 201312-2 ISBN号码

    2024-03-31 22:24:02       17 阅读
  6. spring系列-动态注册bean

    2024-03-31 22:24:02       19 阅读
  7. 微微科技遇到的问题总结

    2024-03-31 22:24:02       18 阅读
  8. 设计模式之命令模式 ,Php高级编程

    2024-03-31 22:24:02       16 阅读
  9. 正则表达式

    2024-03-31 22:24:02       17 阅读
  10. Leetcode 232:用栈实现队列

    2024-03-31 22:24:02       17 阅读
  11. leetcode 55.跳跃游戏

    2024-03-31 22:24:02       18 阅读