2020-03-24 17:49:58

198. 打家劫舍

问题描述:

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
  偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
  偷窃到的最高金额 = 2 + 9 + 1 = 12 。

问题求解:

每个屋子有两个状态,一个被偷了一个是没被偷,我们可以创建一个二维的memo来存储状态。

dp[i][0]:到第i个位置,第i个位置没有被偷的最大金额

dp[i][1]:到第i个位置,第i个位置被偷的最大金额

初始化:dp[0][0] = 0,dp[0][1] = nums[0]

转移方程:dp[i][0] = Math.max(dp[i -1][1], dp[i - 1][0])

dp[i][1] = dp[i - 1][0] + nums[i]

时间复杂度:O(n)

    public int rob(int[] nums) {
if (nums.length == 0) return 0;
int n = nums.length;
int[][] dp = new int[n][2];
dp[0][1] = nums[0];
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = dp[i - 1][0] + nums[i];
}
return Math.max(dp[n - 1][0], dp[n - 1][1]);
}

  

213. 打家劫舍 II

问题描述:

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [2,3,2]
输出: 3
解释: 你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

示例 2:

输入: [1,2,3,1]
输出: 4
解释: 你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
  偷窃到的最高金额 = 1 + 3 = 4 。

问题求解:

上面一题的升级版本,将问题划分成两种状态去依次求解即可。

时间复杂度:O(n)

    public int rob(int[] nums) {
int n = nums.length;
if (n == 0) return 0;
if (n == 1) return nums[0];
return Math.max(helper(Arrays.copyOfRange(nums, 0, n - 1)), helper(Arrays.copyOfRange(nums, 1, n)));
} private int helper(int[] nums) {
int n = nums.length;
int[][] dp = new int[n][2];
dp[0][1] = nums[0];
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1]);
dp[i][1] = dp[i - 1][0] + nums[i];
}
return Math.max(dp[n - 1][0], dp[n - 1][1]);
}

  

337. 打家劫舍 III

问题描述:

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

示例 1:

输入: [3,2,3,null,3,null,1]

3
/ \
2 3
\ \ 
3 1

输出: 7 
解释: 小偷一晚能够盗取的最高金额 = 3 + 3 + 1 = 7.

示例 2:

输入: [3,4,5,1,3,null,1]

3
/ \
4 5
/ \ \ 
1 3 1

输出: 9
解释: 小偷一晚能够盗取的最高金额 = 4 + 5 = 9.

问题求解:

树上动归,逻辑和前面保持一致。

时间复杂度:O(n)

    int res = 0;
public int rob(TreeNode root) {
helper(root);
return res;
} private int[] helper(TreeNode root) {
if (root == null) return new int[]{0, Integer.MIN_VALUE};
int[] l = helper(root.left);
int[] r = helper(root.right);
int[] curr = new int[2];
curr[0] = Math.max(l[0], l[1]) + Math.max(r[0], r[1]);
curr[1] = root.val + l[0] + r[0];
res = Math.max(res, Math.max(curr[0], curr[1]));
return curr;
}

  

1388. 3n 块披萨

问题描述:

给你一个披萨,它由 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 。

示例 2:

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

示例 3:

输入:slices = [4,1,2,5,8,3,1,9,7]
输出:21

示例 4:

输入:slices = [3,1,2]
输出:3

提示:

1 <= slices.length <= 500
slices.length % 3 == 0
1 <= slices[i] <= 1000

问题求解:

该问题可以转化为求不连续n / 3长度子序列的最大和问题。状态转移方程和上面的基本一致,只是多了一个取得个数的维度。

时间复杂度:O(n ^ 2)

    public int maxSizeSlices(int[] slices) {
int n = slices.length;
return Math.max(helper(Arrays.copyOfRange(slices, 0, n - 1)), helper(Arrays.copyOfRange(slices, 1, n)));
} private int helper(int[] nums) {
int n = nums.length;
int k = (n + 1) / 3;
int[][][] dp = new int[n][k + 1][2];
dp[0][1][0] = nums[0];
for (int i = 1; i < n; i++) {
for (int j = 1; j <= Math.min(k, (i + 2) / 2); j++) {
dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1]);
dp[i][j][1] = dp[i - 1][j - 1][0] + nums[i];
}
}
return Math.max(dp[n - 1][k][0], dp[n - 1][k][1]);
}

  

动态规划-不连续最大子序列和-打家劫舍系列-1388. 3n 块披萨的更多相关文章

  1. HDU 1003 Max Sum【动态规划求最大子序列和详解 】

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  2. 【LeetCode】打家劫舍系列(I、II、III)

      打家劫舍(House Robber)是LeetCode上比较典型的一个题目,涉及三道题,主要解题思想是动态规划,将三道题依次记录如下: (一)打家劫舍 题目等级:198.House Robber( ...

  3. HDU1003MAX SUM (动态规划求最大子序列的和)

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  4. HDU 1069 Monkey and Banana (动态规划、上升子序列最大和)

    Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. CSS2系列:BFC(块级格式化上下文)IFC(行级格式化上下文)

    BFC 块级格式化上下文,不好理解,我们暂且把她理解成"具有特殊的一类元素" 哪些元素会生成BFC? 根元素 float属性不为none position为absolute或fix ...

  6. Linux内核系列之Block块层(一)

    .Block块层入口函数为 genhd_device_init(),先对该函数开始分析: 函数实现源码: static int __init genhd_device_init(void) {     ...

  7. TCP连接建立系列 — 连接请求块

    连接请求块(request_sock)之于TCP三次握手,就如同网络数据包(sk_buff)之于网络协议栈,都是核心的数据结构. 内核版本:3.6 Author:zhangskd @ csdn blo ...

  8. (转载)一张表搞清楚西门子S7系列标准DB块与优化DB块

    在TIA Portal中为S7-1200/S7-1500 CPU 添加一个 DB 块时,其缺省属性为优化的 DB ,优化的 DB 块与标准的 DB 块整体对比如下表所示: 项 标准 DB 优化 DB ...

  9. nodejs系列笔记02---模块路径解析

    模块路径解析规则 参考这篇博客 我们已经知道,require函数支持斜杠(/)或盘符(C:)开头的绝对路径,也支持./开头的相对路径.但这两种路径在模块之间建立了强耦合关系,一旦某个模块文件的存放位置 ...

随机推荐

  1. AIDLservice

    有三种情况:如果直接使用服务,则没有必要进行绑定,但是如果要使用服务里面的方法,则要进行绑定.具体的启动情况有下: 其中很重要一点:bindService和unbindService是成对出现的. 1 ...

  2. 混乱中的ICO平台,会不会是下一个P2P的重灾区?

    当众多巨头和创业者还在为共享打车.共享单车.VR.IP化.互联网金融沉迷时,一种全新的"众筹"正在造就一个又一个暴富神话.其名为ICO,即首次代币众筹,一般指区块链初创项目在众筹平 ...

  3. Java NIO-09-零拷贝之 DMA

    DMA 的好处 在介绍DMA之前我想问大家:我们为什么要引入DMA,DMA对我们有什么好处那? 计算机系统中各种常用的数据输入/输出方法有查询方式(包括无条件及条件传送方式)和中断方式,这些方式适用于 ...

  4. 记php封装app 广告植入问题

    <meta http-equiv="X-Frame-Options" content="DENY"> <script type="t ...

  5. 【原创】面试官问我G1回收器怎么知道你是什么时候的垃圾?

    这是why技术的第36篇原创文章 上面的图片是我上周末在家拍的.以后的文章里面我的第一张配图都用自己随手拍下的照片吧.分享生活,分享技术,哈哈. 阳台上的花开了,成都的春天快来了,疫情也应该快要过去了 ...

  6. 微信小程序最新授权方法,getUserInfo

    20180511微信小程序正式关闭原先getUserInfo的逻辑 不再允许自动弹出授权框. 方法一: index.wxml(准备一个用于给用户授权的页面,我这里直接用了一个全屏按钮) <vie ...

  7. 在windows上极简安装GPU版AI框架(Tensorflow、Pytorch)

    在windows上极简安装GPU版AI框架 如果我们想在windows系统上安装GPU版本的AI框架,比如GPU版本的tesnorflow,通常我们会看到类似下面的安装教程 官方版本 安装CUDA 安 ...

  8. python如何在图片上添加文字(中文和英文)

    Python在图片上添加文字的两种方法:OpenCV和PIL 一.OpenCV方法 1.安装cv2 pip install opencv-python 2.利用putText方法来实现在图片的指定位置 ...

  9. 何为引用法---细谈C++引用

    何为引用...给已有的变量取别名 ; int &a = num;//此处 &不是取地址 而是标明 a是引用变量(a 是 num的别名) 注意: 1.引用必须初始化 2.引用一旦初始化 ...

  10. html5特性简要概括

    1.html5主要的设计目的: 互联网语义化,以便更好地被人类和机器阅读 更好的在移动设备上支持web应用 https://www.w3.org/TR/html5 新增内容: 新的语义标签 <h ...