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

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

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

示例 1:

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

这条比较难的一点是论证:

题目可以转换为,取任意 n/3 个不相邻的数字的最大和。

1、首先显然相邻的两个数字是不可能同时取到的。

2、任意长度为 n/3 的不相邻的子序列都可以被取到。

  尝试简单论证一下,

  用0表示不选择,1表示选择,当选择不相邻的n/3个数字之后,001001001 这样的序列可以表示为一种选取方法。

  显然,存在某个1的周围有至少三个0,如 0010 或 0100 (由于是一个圆 首尾时相连接的)

  因为如果不存在的话,则序列只能为 010101... 显然 1 的个数会大于 n/3

  然后先选取这样的 1 和周围的两个 0 ,那么,剩下还是会有一个 0,(不会出现两个1相邻)

  则剩下的序列还是满足最开始的条件,继续以同样的规则选择直到结束最后剩下010。

  举例说明:

  001010100

  先取第一个1和旁边的0 变为 010100

  取后面的1和旁边的0 变为 010 最后全部取走。

如果能想到上面的结论,剩下的就只是一个简单的DP了,DP[i][j] 表示取i块,最后一块序列为j的最大值,由于第一块和最后一块不能同时取,所以需要计算两次。其实和这道题蛮像的 https://leetcode-cn.com/problems/house-robber-ii/

class Solution {
public:
int maxSizeSlices(vector<int>& slices) {
int n = slices.size();
int select = n / 3;
int dp1[select + 1][n];
int dp2[select + 1][n];
memset(dp1, 0, sizeof dp1);
memset(dp2, 0, sizeof dp2);
dp1[1][0] = slices[0];
dp2[1][1] = slices[1];
for (int i = 1; i <= select; i++) {
for (int j = 2; j < n; j++) {
for (int k = 0; k < j - 1; k++) {
dp1[i][j] = max(dp1[i][j], dp1[i-1][k] + slices[j]);
dp2[i][j] = max(dp2[i][j], dp2[i-1][k] + slices[j]);
}
}
}
int ans = 0;
for (int i = 0; i < n - 1; i++) {
ans = max(ans, dp1[select][i]);
}
for (int i = 0; i < n; i++) {
ans = max(ans, dp2[select][i]);
}
return ans;
}
};

三层循环可以简化为两层循环

class Solution {
public:
int maxSizeSlices(vector<int>& slices) {
int n = slices.size();
int select = n / 3;
int dp1[select + 1][n];
int dp2[select + 1][n];
memset(dp1, 0, sizeof dp1);
memset(dp2, 0, sizeof dp2);
dp1[1][0] = slices[0];
dp2[1][1] = slices[1];
int max1, max2;
for (int i = 1; i <= select; i++) {
max1 = dp1[i-1][0];
max2 = dp2[i-1][0];
for (int j = 2; j < n; j++) {
dp1[i][j] = max1 + slices[j];
dp2[i][j] = max2 + slices[j];
max1 = max(max1, dp1[i-1][j-1]);
max2 = max(max2, dp2[i-1][j-1]);
}
}
int ans = 0;
for (int i = 0; i < n - 1; i++) {
ans = max(ans, dp1[select][i]);
}
for (int i = 0; i < n; i++) {
ans = max(ans, dp2[select][i]);
}
return ans;
}
};

LeetCode 1388. Pizza With 3n Slices(3n 块披萨)(DP)的更多相关文章

  1. 动态规划-不连续最大子序列和-打家劫舍系列-1388. 3n 块披萨

    2020-03-24 17:49:58 198. 打家劫舍 问题描述: 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统, ...

  2. Java实现 LeetCode 769 最多能完成排序的块(单向遍历)

    769. 最多能完成排序的块 数组arr是[0, 1, -, arr.length - 1]的一种排列,我们将这个数组分割成几个"块",并将这些块分别进行排序.之后再连接起来,使得 ...

  3. Java实现 LeetCode 768 最多能完成排序的块 II(左右便利)

    768. 最多能完成排序的块 II 这个问题和"最多能完成排序的块"相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8. arr是一个可能包含 ...

  4. Leetcode 详解(股票交易日)(动态规划DP)

    问题描述: 在股市的交易日中,假设最多可进行两次买卖(即买和卖的次数均小于等于2),规则是必须一笔成交后进行另一笔(即买-卖-买-卖的顺序进行).给出一天中的股票变化序列,请写一个程序计算一天可以获得 ...

  5. Leetcode: Combination Sum IV && Summary: The Key to Solve DP

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  6. leetcode 201. Bitwise AND of Numbers Range(位运算,dp)

    Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...

  7. 第十六周 Leetcode 600. Non-negative Integers without Consecutive Ones(HARD) 计数dp

    Leetcode600 很简单的一道计数题 给定整数n 求不大于n的正整数中 二进制表示没有连续的1的数字个数 在dp过程中只要保证不出现连续1以及大于n的情况即可. 所以设计按位dp[i][j]表示 ...

  8. LeetCode 1223. 掷骰子模拟 Dice Roll Simulation - Java - DP

    题目链接:1223. 掷骰子模拟 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数. 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[ ...

  9. Java实现 LeetCode 813 最大平均值和的分组 (DFS+DP记忆化搜索)

    813. 最大平均值和的分组 我们将给定的数组 A 分成 K 个相邻的非空子数组 ,我们的分数由每个子数组内的平均值的总和构成.计算我们所能得到的最大分数是多少. 注意我们必须使用 A 数组中的每一个 ...

  10. Leetcode 137.只出现一次的数字II

    只出现一次的数字II 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? ...

随机推荐

  1. iframe嵌入svg图片动态更改文本样式并进行缩放等功能实现拓扑图

    好久没更了,近期开发遇到的需求,抽空梳理一下~ 需求:实现一个复杂的拓扑图,图中元素的个数,以及各个参数内容是动态展示的. 于是让ui提供了对应的svg图片. 解决思路:使用iframe嵌入svg图片 ...

  2. php执行出现权限问题

  3. 写写Redis十大类型bitmap的常用命令

    其实这些命令官方上都有,而且可读性很强,还有汉化组翻译的http://redis.cn/commands.html,不过光是练习还是容易忘,写一写博客记录一下 bitmap 位图,是由0和1状态表现的 ...

  4. ipa文件上传到app store的构建版本的工具

    打包好ipa文件后,可以使用mac电脑上的xcode将ipa上传到app store的构建版本中,假如没有mac电脑,可以使用香蕉云编来将ipa文件上传到构建版本. 这里我们来介绍下ipa文件上传到a ...

  5. adb对安卓app进行抓包(ip连接设备)

    adb对安卓app进行抓包(ip连接设备) 一,首先将安卓设备的开发者模式打开,提示允许adb调试 二,自己的笔记本要和安卓设备在同一个网段下(同连一个WiFi就可以了) 三,在笔记本上根据ip来连接 ...

  6. iOS开发基础144-逐字打印效果

    在AIGC类的APP中,实现那种一个字一个字.一行一行地打印出文字的效果,可以通过多种方法来实现.下面是一些实现方法,使用Swift和OC来举例说明. OC版 1. 基于定时器的逐字打印效果 可以使用 ...

  7. LinuxUDP通讯

    目录 前言 一.UDP通讯 1.UDP通讯概述 2.UDP的特点 3.UDP的应用 二.UDP基本通讯 1.socket函数 2.bind函数 2.1 主机字节序和网络字节序 2.2 点分制十进制转换 ...

  8. 4、SpringBoot2之整合SpringMVC

    创建名为springboot_springmvc的新module,过程参考3.1节 4.1.重要的配置参数 在 spring boot 中,提供了许多和 web 相关的配置参数(详见官方文档),其中有 ...

  9. 【Vue】Re21 VueX 第二部分(Mutations)

    一.Mutations携带参数处理 Store状态的更新唯一方式:提交Mutations Mutations包含两部分: 1.字符串的事件类型[TYPE] 2.一个回调函数[HANDLER] 该函数的 ...

  10. 读论文《Distilling the Knowledge in a Neural Network》——蒸馏网络 —— 蒸馏算法 —— 知识蒸馏 中的温度系数到底怎么用, temperature怎么用?

    论文地址: https://arxiv.org/pdf/1503.02531.pdf 蒸馏网络的重要公式: 其中,\(p^g\)为Teacher网络,\(q\)为Student网络. 个体神经网络(C ...