首页 > 其他分享 >Leetcode 1388. 3n 块披萨

Leetcode 1388. 3n 块披萨

时间:2023-08-18 19:25:29浏览次数:48  
标签:slices int 披萨 len start 1388 Leetcode dp

(本文只提供了解题思路的思考,原文作者题解连接)
先把题目粘贴在这里

给你一个披萨,它由 3n 块不同大小的部分组成,现在你和你的朋友们需要按照如下规则来分披萨:

你挑选 任意 一块披萨。
Alice 将会挑选你所选择的披萨逆时针方向的下一块披萨。
Bob 将会挑选你所选择的披萨顺时针方向的下一块披萨。
重复上述过程直到没有披萨剩下。
每一块披萨的大小按顺时针方向由循环数组 slices 表示。

请你返回你可以获得的披萨大小总和的最大值。

输入:slices = [1,2,3,4,5,6]
输出:10
解释:选择大小为 4 的披萨,Alice 和 Bob 分别挑选大小为 3 和 5 的披萨。然后你选择大小为 6 的披萨,Alice 和 Bob 分别挑选大小为 2 和 1 的披萨。你获得的披萨总大小为 4 + 6 = 10 。


输入:slices = [8,9,8,6,1,1]
输出:16
解释:两轮都选大小为 8 的披萨。如果你选择大小为 9 的披萨,你的朋友们就会选择大小为 8 的披萨,这种情况下你的总和不是最大的。

提示:

  • 1 <= slices.length <= 500
  • slices.length % 3 == 0
  • 1 <= slices[i] <= 1000
class Solution {
    public int maxSizeSlices(int[] slices) {
        if (slices == null || slices.length == 0) return 0;
        if (slices.length == 1) return slices[0];
        if (slices.length == 2) return Math.max(slices[0], slices[1]);

        int len = slices.length;
        int n = len / 3;
        return Math.max(maxTakebyRange(slices, 0, len - 2, n), maxTakebyRange(slices, 1, len - 1, n));

    }

    private int maxTakebyRange(int[] slices, int start, int end, int n) {
        if (start == end) return slices[start];
        int len = end - start + 1;

        //dp[i][j] = the max size we can get, range: [0, i], picked count: j
        int[][] dp = new int[len][n + 1];

        //base condition
        dp[0][0] = 0;
        dp[0][1] = slices[start];
        dp[1][0] = 0;
        dp[1][1] = Math.max(slices[start], slices[start + 1]);

        //dp transfer
        for (int i = 2; i < len; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = Math.max(dp[i - 2][j - 1] + slices[start + i], dp[i - 1][j]);
            }
        }

        return dp[len - 1][n];
    }
}

接下来是我对于此代码的理解:
先把前几种情况写出
第一种情况:数组为空,返回0;
第二种情况:数组长度为1,返回数组首元素;
第三种情况:数组长度为2,返回数组两元素最大值
再将数组长度定义为len,n定义为可以选几次

接下来就是动态规划的部分,但我算法基础比较弱,所以对此理解得不深,希望有大神可以指导我

开始也是头等于尾的情况,直接返回头
这里又再次定义了一个长度len=end-start+1,结果和上面定义的slices.length应该是相同的,那为什么没有直接引用上述呢,哦!!!对,这段代码是不同start的,所以长度不一定相同
接下来就准备开始进行dp了
定义了dp[len][n+1],长度和slices.length/3+1,这里又是为何如此设置呢?
我来举个例子看看我能不能搞明白,
slices 1 2 3 4 5 6 7
下标 0 1 2 3 4 5 6
start=0 时,len=7,n=int(7/3)=2,dp[len][n+1]=dp[7][3]
start=1 时,len=6,n=int(6/3)=2,dp[len][n+1]=dp[6][3]
看起来是为了让选择次数相等。

之后更新了基础条件,以供后面的遍历使用
dp[0][0] = 0 表示在范围 [0, 0] 内不选择切片,所以最大切片大小为0;
dp[0][1] = slices[start] 表示在范围 [0, 0] 内选择一个切片,所以最大切片大小为 slices[start];
dp[1][0] = 0 表示在范围 [0, 1] 内不选择切片,所以最大切片大小为0;
dp[1][1] = max(slices[start], slices[start + 1]) 表示在范围 [0, 1] 内选择一个切片,所以最大切片大小为 slices[start] 和 slices[start + 1] 中的最大值。

接下来,使用双重循环来计算动态规划的转移方程。外层循环从2开始,内层循环从1开始。循环变量 i 表示当前的范围终止索引,循环变量 j 表示当前选择的切片数量。
在每次循环中,通过对比两种选择:选择当前切片和不选择当前切片,来更新 dp[i][j] 的值。动态转移方程为:
dp[i][j] = max(dp[i - 2][j - 1] + slices[start + i], dp[i - 1][j])
其中,dp[i - 2][j - 1] + slices[start + i] 表示选择当前切片,dp[i - 1][j] 表示不选择当前切片。
最后,返回 dp[len - 1][n],即在整个范围内选择 n 个切片时的最大切片大小。

标签:slices,int,披萨,len,start,1388,Leetcode,dp
From: https://www.cnblogs.com/benfang/p/17641410.html

相关文章

  • leetcode1372dp求交错路径长
    bfd+dpunordered_map<TreeNode*,int>d,p;queue<pair<TreeNode*,TreeNode*>>q;intdp(TreeNode*root){d[root]=p[root]=0;q.push({root,nullptr});while(!q.empty()){autox=q.front();q.pop();autoy=x.second();......
  • [LeetCode][70]climbing-stairs
    ContentYouareclimbingastaircase.Ittakesnstepstoreachthetop.Eachtimeyoucaneitherclimb1or2steps.Inhowmanydistinctwayscanyouclimbtothetop? Example1:Input:n=2Output:2Explanation:Therearetwowaystoclimbtothet......
  • [LeetCode][62]unique-paths
    ContentThereisarobotonanmxngrid.Therobotisinitiallylocatedatthetop-leftcorner(i.e.,grid[0][0]).Therobottriestomovetothebottom-rightcorner(i.e.,grid[m-1][n-1]).Therobotcanonlymoveeitherdownorrightatanypointi......
  • [LeetCode][64]minimum-path-sum
    ContentGivenamxngridfilledwithnon-negativenumbers,findapathfromtoplefttobottomright,whichminimizesthesumofallnumbersalongitspath.Note:Youcanonlymoveeitherdownorrightatanypointintime. Example1:Input:grid=[[......
  • [LeetCode][55]jump-game
    ContentYouaregivenanintegerarraynums.Youareinitiallypositionedatthearray'sfirstindex,andeachelementinthearrayrepresentsyourmaximumjumplengthatthatposition.Returntrueifyoucanreachthelastindex,orfalseotherwise.......
  • [LeetCode][32]longest-valid-parentheses
    ContentGivenastringcontainingjustthecharacters'('and')',returnthelengthofthelongestvalid(well-formed)parenthesessubstring. Example1:Input:s="(()"Output:2Explanation:Thelongestvalidparentheses......
  • [LeetCode][53]maximum-subarray
    ContentGivenanintegerarraynums,findthesubarraywiththelargestsum,andreturnitssum. Example1:Input:nums=[-2,1,-3,4,-1,2,1,-5,4]Output:6Explanation:Thesubarray[4,-1,2,1]hasthelargestsum6.Example2:Input:nums=[1]Output:......
  • [LeetCode][10]regular-expression-matching
    ContentGivenaninputstrings andapatternp,implementregularexpressionmatchingwithsupportfor'.'and'*'where:'.'Matchesanysinglecharacter.​​​​'*'Matcheszeroormoreoftheprecedingelement.T......
  • [LeetCode][42]trapping-rain-water
    ContentGivennnon-negativeintegersrepresentinganelevationmapwherethewidthofeachbaris1,computehowmuchwateritcantrapafterraining. Example1:Input:height=[0,1,0,2,1,0,1,3,2,1,2,1]Output:6Explanation:Theaboveelevationmap......
  • LeetCode[64]MinimumPathSum
    ContentGivenamxngridfilledwithnon-negativenumbers,findapathfromtoplefttobottomright,whichminimizesthesumofallnumbersalongitspath.Note:Youcanonlymoveeitherdownorrightatanypointintime. Example1:Input:grid=[[......