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. 自动化移动安全渗透测试框架:Mobile Security Framework

    自动化移动安全渗透测试框架:Mobile Security Framework 译/Sphinx  测试开发社区  7月3日 Mobile Security Framework (移动安全框架) 是一 ...

  2. MySQL安装和常用命令

    一.安装MySQL groupadd mysqluseradd -r -g mysql mysqlgroups mysqlfind / -name mysql | xargs rm -rfwget h ...

  3. 机器学习技法笔记(2)-Linear SVM

    从这一节开始学习机器学习技法课程中的SVM, 这一节主要介绍标准形式的SVM: Linear SVM 引入SVM 首先回顾Percentron Learning Algrithm(感知器算法PLA)是 ...

  4. DIY电压基准测万用表

    | 分类 日志  | 手里有三个常用的手持表,UT61E四位半,优利德明星产品:福禄克F117C,换挡快,单手操作还带LoZ:UT210E小钳表能够通过修改EEPROM更改电表配置,已经刷了6000字 ...

  5. linux中nginx、mysql安装碰到的问题

    服务器到期新买了一台服务器,记录一下重新安装基本环境碰到了一些问题 安装nginx 1. 启动失败 403 forbidden nginx 解决方案:(个人使用直接用了root账号,修改对应nginx ...

  6. docker学习读书笔记-一期-整理

    0.Docker - 第零章:前言 1.Docker - 第一章:Docker简介 2.Docker - 第二章:第一个Docker应用 3.Docker - 第三章:Docker常用命令 4.Doc ...

  7. GDB调试系列之了解GDB

    想要熟练利用GDB进行程序调试,首先要了解什么是GDB. 1. 什么是GDB GDB (the GNU Project Debugger) 是一个可以运行在大多数常见的UNIX架构.Windows.M ...

  8. nx-admin1.2版本发布

    nx-admin 是一个开源的管理系统前端集成方案 github地址 nx-admin的初心 组件更易用, 让每个小白快速上手, 最大程度上帮助个人,企业节省时间成本和费用开支. 尽管这个过程不简单, ...

  9. 前端每日实战:27# 视频演示如何用纯 CSS 创作一个精彩的彩虹 loading 特效

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/vjvoow 可交互视频教程 此视频 ...

  10. 我折腾的shell笔记

    目录 Mac一些常用的快捷键记录 iTerm2或者命令行相关 Mac桌面上或者某目录下操作 一些实用脚本示例 代码无提示或者其他抽风症状,清除Xcode缓存 查看当前网络ip地址 日常提交推送git代 ...