[程序员代码面试指南]递归和动态规划-排成一条线的纸牌博弈问题(DP)

题目

给定一个整型数组arr,代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿,但是每个玩家每次只能拿走最左或最右的纸牌,玩家A和玩家B都绝顶聪明。请返回最后获胜者的分数。

例子

arr=[1,2,100,4]。
开始时玩家A只能拿走1或4。如果玩家A拿走1,则排列变为[2,100,4],接下来玩家B可以拿走2或4,然后继续轮到玩家A。如果开始时玩家A拿走4,则排列变为[1,2,100],接下来玩家B可以拿走1或100,然后继续轮到玩家A。玩家A作为绝顶聪明的人不会先拿4,因为拿了4之后玩家B将拿走100。所以玩家A会先拿1,让排列变为[2,100,4],接下来玩家B不管怎么选,100都会被玩家A拿走。玩家A会获胜,分数为101。所以返回101。
arr=[1,100,2]。
开始时玩家A不管拿1还是2,玩家B作为绝顶聪明的人,都会把100拿走。玩家B会获胜,分数为100。所以返回100。

题解

  • 两个dp数组 offensivePos[i,j]、 defensivePos[i,j] 分别表示对于arr[i,j],当前为先手能够获得的最大得分、当前为后手能够获得的最大的分。
  • 初始化:当i=j ,offensivePos[j][j]=arr[j] , defensivePos[i,j] =0.
  • 其他位置两个数组的转移方程见代码。
  • 遍历顺序是"从上往下从后往左"
  • 时间复杂度O(n^2) ,额外空间复杂度O(n^2).

代码

public class Main {
    public static void main(String args[]) {
        int[] arr= {1,2,100,4};
        int winNum=getWinNum(arr);
        System.out.println(winNum);
    }

    public static int getWinNum(int[] arr) {
        if(arr.length==0) {
            return 0;
        }
        int[][] offensivePos=new int[arr.length][arr.length];
        int[][] defensivePos=new int[arr.length][arr.length];
        for(int j=0;j<arr.length;++j) {//由上至下
            offensivePos[j][j]=arr[j];
            for(int i=j-1;i>=0;--i) {//由右至左
                offensivePos[i][j]=Math.max(arr[i]+defensivePos[i+1][j], arr[j]+defensivePos[i][j-1]);//
                defensivePos[i][j]=Math.min(offensivePos[i+1][j], offensivePos[i][j-1]);
            }
        }
        return Math.max(defensivePos[0][arr.length-1], offensivePos[0][arr.length-1]);
    }
}

原文地址:https://www.cnblogs.com/coding-gaga/p/10952212.html

时间: 2024-08-08 19:27:05

[程序员代码面试指南]递归和动态规划-排成一条线的纸牌博弈问题(DP)的相关文章

[程序员代码面试指南]递归和动态规划-机器人达到指定位置方法数(一维DP待做)

题目描述 一行N个位置1到N,机器人初始位置M,机器人可以往左/右走(只能在位置范围内),规定机器人必须走K步,最终到位置P.输入这四个参数,输出机器人可以走的方法数. 解题思路 DP 方法一:时间复杂度O(NK),空间复杂度O(NK) 方法二:时间复杂度O(NK),空间复杂度O(N) 方法一代码 //ans=walk(N,M,K,P); public static int walk(int N,int cur,int rest,int P) { int[][] dp=new int[rest+

[程序员代码面试指南]递归和动态规划-最长公共子串问题

题目描述 给定两个串,输出最长公共子串. 解题思路 维护dp[i][j],表示子串str1[0:i+1]与str2[0:j+1]的最长公共子串长度. 由dp[][]右下角开始,找公共子串. 代码 public class Solution{ private int[][] getDp(char[] str1,char[] str2){ int[][] dp=new int[str1.length][str2.length]; int temp=0; for(int i=0;i<str1.leng

[程序员代码面试指南]递归和动态规划-换钱的最少货币数

题目描述 给定arr,arr中所有的值都为正数且不重复.每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim,求组成aim的最少货币数. 解题思路 dp[i][j]表示只用第0到i种货币,凑成j元的最小货币张数. 初始化: 转移方程: dp[i][j]=min{dp[i-1][j-k*arr[i]]+k} (k>=0) 整理得 dp[i][j]=min{dp[i-1][j],min{dp[i-1][j-k*arr[i]]+k}} (k>=1) 变换得 dp[i][j]=

程序员代码面试指南 IT名企算法与数据结构题目最优解 ,左程云著pdf高清版免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介  · · · · · ·这是一本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现.针对当前程序员面试缺乏权威题目汇总这一痛点,本书选取将近200道真实出现过的经典代码面试题,帮助广大程序员的面试准备做到万无一失.“刷”完本书后,你就是“题王”!__eol__本书采用题目+解答的方式组织内容,并把面试题类型相近或者解法相近的题目尽量放在一起,读者在学习本书时很容易看出面试题解法之间的联系,使知识的学习避免碎片化

[程序员代码面试指南]二叉树问题-计算完全二叉树节点数

题意 计算完全二叉树节点数. 题解 不使用遍历方法,优化时间复杂度到O(H^2). 高度为h的满二叉树节点数为2^h-1. 设计递归函数search(Node root,int h,int H),返回当前节点roo为根的完全二叉树的节点数.h代表该节点在的高度,高度从1计算,H代表原始二叉树的高度始终不变. t判断当前节点的右子树的最左边的节点的高度. -若和该树的高度一致,则说明左子树为满二叉树,节点数=由上式得到的左子树节点数+本节点数1+递归得到的右子树节点数. 若高度不一致,则说明右子树

[程序员代码面试指南]二叉树问题-派对的最大快乐值

题意 一棵多叉树代表员工的上下级关系,孩子节点是父节点的直接下级.节点代表员工,属性包括快乐值和孩子节点列表. 大家参加了party,要求一个员工去了则它的所有直接下级都不能去,问参加party能得到的最大快乐值是多少. 题解 我原本的思路是一层员工去不去是它上面一层去和不去两种状态转移过来的,但是也注意一层的员工可以有的去有的不去,所以应该按节点看. 按节点看状态,分根节点去和不去讨论快乐值最大值怎么由所有孩子节点转移来,递归是从下得到上的,叶子节点很好初始化. 并且一个节点自己去不去的两种返

《程序员代码面试指南》第八章 数组和矩阵问题 将正方形矩阵顺时针转动90

题目 将正方形矩阵顺时针转动90 java代码 package com.lizhouwei.chapter8; /** * @Description: 将正方形矩阵顺时针转动90 * @Author: lizhouwei * @CreateDate: 2018/4/28 22:16 * @Modify by: * @ModifyDate: */ public class Chapter8_2 { public void rotate(int[][] matrix) { int tR = 0; i

《程序员代码面试指南》第八章 数组和矩阵问题 需要排序的最短子数组长度

题目 需要排序的最短子数组长度 java代码 package com.lizhouwei.chapter8; /** * @Description: 需要排序的最短子数组长度 * @Author: lizhouwei * @CreateDate: 2018/4/29 8:03 * @Modify by: * @ModifyDate: */ public class Chapter8_5 { public int getMinLength(int[] arr) { if (arr == null

《程序员代码面试指南》第八章 数组和矩阵问题 &quot;之&quot;字形打印矩阵

题目 "之"字形打印矩阵 java代码 package com.lizhouwei.chapter8; /** * @Description: "之"字形打印矩阵 * @Author: lizhouwei * @CreateDate: 2018/4/28 22:53 * @Modify by: * @ModifyDate: */ public class Chapter8_3 { public void printMatrixZigZag(int[][] matri