Leetcode 1349. 参加考试的最大学生数(Java + 按行状压暴力 + DP)

文章目录

  • 题目
  • 思路
    • Java + 按行状压暴力 + DP:
    • 第 1 步:
    • 第 2 步:
    • 第 3 步:
    • 第 4 步:
  • 复杂度
  • Code

题目

  • Problem: 1349. 参加考试的最大学生数
  • 给你一个 m * n 的矩阵 seats 表示教室中的座位分布。如果座位是坏的(不可用),就用 ‘#’ 表示;否则,用 ‘.’ 表示。
  • 学生可以看到左侧、右侧、左上、右上这四个方向上紧邻他的学生的答卷,但是看不到直接坐在他前面或者后面的学生的答卷。请你计算并返回该考场可以容纳的同时参加考试且无法作弊的 最大 学生人数。
  • 学生必须坐在状况良好的座位上。
  • seats 只包含字符 ‘.’ 和’#’
  • m == seats.length
  • n == seats[i].length
  • 1 <= m <= 8
  • 1 <= n <= 8

思路

Java + 按行状压暴力 + DP:

第 1 步:

  • 首先思考每个好座位选或不选的 DFS 暴力求解,会超时
  • 其次分析题意可知,仅有相邻两行之间有限制,
  • 因此可以想到将行拆开,仅每一行去暴力所有可能,使用 DP 判断相邻两行的限制即可

第 2 步:

  • 每行暴力:
  • 每行遍历从 0 到 (2 ^ n) - 1 的数字 seat,seat 转化为二进制、1 代表有人,
  • isRowUsableSeat 行内满足要求:遍历每个 1 相邻左侧没有 1 且 每个 1 均是好座位,
  • 此 seat 代表该行内部满足条件,

第 3 步:

  • DP 判断两行的限制:
  • 定义状态:dp[i][seat] 代表前 i 行中,第 i 行座位为 seat 时的最大学生数
  • 初始化:dp[0][isRowUsableSeat(seat)] = countOne(seat)(seat 中 1 个个数),代表第一行没有限制
  • 状态转移方程:
    • dp[i][isRowUsableSeat(seat)] = countOne(seat) + max(isCrossUsableSeat(0, seat)?dp[i-1][0]):0 , … , isCrossUsableSeat((2 ^ n) - 1, seat)?dp[i-1][(2 ^ n) - 1]:0)
  • 其中 isCrossUsableSeat(seat1, seat2) 代表两行(seat1-上一行、seat2-下一行)是否满足要求,即 seat2 每个 1 的下标 col、在 seat1 中 col-1 与 col+1 都不存在 1

第 4 步:

  • 预处理所有 isCrossUsableSeat,
  • 由于 i 仅与 i-1 相关,因此使用滚动数组即可

复杂度

时间复杂度:

时间复杂度: O ( ( m + n ) ∗ 2 2 n ) O((m + n) * 2 ^ {2n}) O((m+n)22n)

空间复杂度:

空间复杂度: O ( n ∗ 2 2 n ) O(n * 2 ^ {2n}) O(n22n)

Code

class Solution {/*** Java + 按行状压暴力 + DP:** 第 1 步:* 首先思考每个好座位选或不选的 DFS 暴力求解,会超时* 其次分析题意可知,仅有相邻两行之间有限制,* 因此可以想到将行拆开,仅每一行去暴力所有可能,使用 DP 判断相邻两行的限制即可** 第 2 步:* 每行暴力:* 每行遍历从 0 到 (2 ^ n) - 1 的数字 seat,seat 转化为二进制、1 代表有人,* isRowUsableSeat 行内满足要求:遍历每个 1 相邻左侧没有 1 且 每个 1 均是好座位,* 此 seat 代表该行内部满足条件,** 第 3 步:* DP 判断两行的限制:* 定义状态:dp[i][seat] 代表前 i 行中,第 i 行座位为 seat 时的最大学生数* 初始化:dp[0][isRowUsableSeat(seat)] = countOne(seat)(seat 中 1 个个数),代表第一行没有限制* 状态转移方程:dp[i][isRowUsableSeat(seat)] = countOne(seat) * + max(isCrossUsableSeat(0, seat)?dp[i-1][0]):0 , ... , isCrossUsableSeat((2 ^ n) - 1, seat)?dp[i-1][(2 ^ n) - 1]:0)* 其中 isCrossUsableSeat(seat1, seat2) 代表两行(seat1-上一行、seat2-下一行)是否满足要求,即 seat2 每个 1 的下标 col、在 seat1 中 col-1 与 col+1 都不存在 1** 第 4 步:* 预处理所有 isCrossUsableSeat,* 由于 i 仅与 i-1 相关,因此使用滚动数组即可* 时间复杂度:O((m + n) * 2 ^ 2n),空间复杂度:O(n * 2 ^ 2n)**/public int maxStudents(char[][] seats) {int m = seats.length;int n = seats[0].length;int seatTotal = 1 << n;// 预处理所有 isCrossUsableSeatboolean[][] crossUsableSeat = preCrossUsableSeat(seatTotal);int[][] dp = new int[2][seatTotal];// 初始化for (int j = 0; j < seatTotal; j++) {// 第 0 行满足 isRowUsableSeatif (isRowUsableSeat(seats[0], j)) {dp[0][j] = countOne(j);}}// 状态转移方程:dp[i][isRowUsableSeat(seat)] = countOne(seat) // + max(isCrossUsableSeat(0, seat)?dp[i-1][0]):0 , ... , isCrossUsableSeat((2 ^ n) - 1, seat)?dp[i-1][(2 ^ n) - 1]:0)for (int i = 1; i < m; i++) {for (int j = 0; j < seatTotal; j++) {// 第 i 行内满足条件if (isRowUsableSeat(seats[i], j)) {int countOneJ = countOne(j);for (int k = 0; k < seatTotal; k++) {// 第 i 行与 i-1 行满足条件if (crossUsableSeat[j][k]) {dp[i & 1][j] = Math.max(dp[i & 1][j], dp[(i - 1) & 1][k] + countOneJ);}}}}}int res = 0;for (int j = 0; j < seatTotal; j++) {res = Math.max(res, dp[(m - 1) & 1][j]);}return res;}/*** 遍历每个 1:相邻左侧没有 1 且 每个 1 均是好座位*/private boolean isRowUsableSeat(char[] seats, int seat) {for (int i = 0; (1 << i) <= seat; i++) {if (((1 << i) & seat) > 0) {if (seats[i] == '#' || ((1 << i + 1) & seat) > 0) {return false;}}}return true;}/*** 预处理所有 isCrossUsableSeat,*/private boolean[][] preCrossUsableSeat(int seatTotal) {boolean[][] crossUsableSeat = new boolean[seatTotal][seatTotal];// seat2 每个 1 的下标 col、在 seat1 中 col-1 与 col+1 都不存在 1for (int seat1 = 0; seat1 < seatTotal; seat1++) {for (int seat2 = 0; seat2 < seatTotal; seat2++) {if (isCrossUsableSeat(seat1, seat2)) {crossUsableSeat[seat1][seat2] = true;}}}return crossUsableSeat;}private boolean isCrossUsableSeat(int seat1, int seat2) {for (int bitNum = (seat2 & -seat2); bitNum > 0; bitNum = (seat2 & -seat2)) {if ((bitNum != 1 && (seat1 & (bitNum >> 1)) > 0) || ((seat1 & (bitNum << 1)) > 0)) {return false;}seat2 -= bitNum;}return true;}/*** 二进制 1 的个数*/private int countOne(int seat) {int res = 0;while (seat > 0) {seat &= seat - 1;res++;}return res;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/578053.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Midjourney】Midjourney提示词格式详解

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;Midjourney提示词格式 &#x1f341; 1.模型版本提示词&#x1f341; 参数 参数详解 应用示例 &#x1f343; 2.风格…

基于双闭环PI的SMO无速度控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于双闭环PI的SMO无速度控制系统simulink建模与仿真&#xff0c;基于双闭环PI的SMO无速度控制系统主要由两个闭环组成&#xff1a;一个是电流环&#xff0c;另一个是速度环。…

AssertionError: The environment must specify an action space. 报错 引发的惨案

起因是&#xff1a;从github上下载了一个代码&#xff0c;运行出错。 整体流程&#xff1a; 1. AssertionError: The environment must specify an action space. 报错&#xff0c;解决方案是 降级gym到 gym0.18.0 2.为了降级gym gym0.18.0 报错&#xff0c;发现需要降级 setup…

Linux scp命令教程:如何安全地在Linux机器之间复制文件(附案例详解和注意事项)

Linux scp命令介绍 scp命令是Secure Copy的缩写&#xff0c;它是一个基于SSH的命令行工具&#xff0c;用于在两个位置之间安全地复制文件和目录。使用scp&#xff0c;你可以从本地系统复制文件或目录到远程系统&#xff0c;从远程系统复制文件或目录到本地系统&#xff0c;或者…

k8s实战之ELK日志管理

首先查看总体流程 首先创建namespace apiVersion: v1 kind: Namespace metadata:name: kube-logging 一、首先创建es.yaml --- apiVersion: v1 #kubernetes API版本,采用最新版本v1 kind: Service #资源类型定义为Service metadata: name: elasticsearch-logging # …

vue3 全局配置Axios实例

目录 前言 配置Axios实例 页面使用 总结 前言 Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;用于浏览器和 Node.js 环境。它提供了一种简单、一致的 API 来处理HTTP请求&#xff0c;支持请求和响应的拦截、转换、取消请求等功能。关于它的作用&#xff1a; 发起 HTTP …

音视频技术开发周刊 | 325

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 AI读心术震撼登顶会&#xff01;模型翻译脑电波&#xff0c;人类思想被投屏&#xff5c;NeurIPS 2023 在最近举办的NeurIPS大会上&#xff0c;研究人员展示了当代AI更震撼…

CSS Grid 网格布局简要说明

grid网格布局&#xff0c;是一个二维系统&#xff0c;可以像表格一样将页面容器分割成一块一块的区域&#xff0c;定义子元素的排布和位置。 简单使用&#xff1a; 对父元素设置dispay&#xff1a;grid;grid-template-colums和grid-template-rows来设置几行几列 1. grid-temp…

CMakeLists.txt

源码结构 生成可执行程序 # CMake最小版本号 cmake_minimum_required(VERSION 3.15.0)#增加-stdc11 set(CMAKE_CXX_STANDARD 11)#设置工程名称 project(calculate)#[[ #方法一&#xff1a;添加源码文件 #aux_source_directory(< dir > < variable >) #dir&#xf…

c# 比较对象是否相同

在C#中&#xff0c;比较两个对象是否相同可以有以下几种方法&#xff1a; ReferenceEquals(object o1, object o2)&#xff1a; 这是一个静态方法&#xff0c;用于比较两个对象的引用是否指向堆中的同一块内存。如果两个对象是同一个实例或者都是 null&#xff0c;那么返回 tru…

python异常之assert语句

1 python异常之assert语句 python的assert语句&#xff0c;是一个断言语句。 用于断言某个表达式的值是否符合预期&#xff0c;不符合则停止运行&#xff0c;并且触发AssertionError异常。 1.1 基本用法 用法 assert test_cond [,err_msg]描述 test_cond&#xff1a;要测…

FreeSWITCH continue_on_fail

先看一段简单的dialplan&#xff1a; <action application"set" data"continue_on_failtrue"/> <action application"bridge" data"user/1001"/> <action application"log" data"ERR run here"/&g…

【JDK新特性】JDK和Springboot各版本新特性介绍

目录 参考资料 以下是一些较新版本的JDK的主要新特性介绍&#xff1a; JDK 8&#xff1a; Lambda 表达式&#xff1a;引入了函数式编程的概念&#xff0c;使得代码更简洁、可读性更强。Stream API&#xff1a;提供了一种高效处理集合数据的方式&#xff0c;支持并行处理。默认…

Python能做大项目(7) - Poetry: 项目管理的诗和远方之二

依赖管理 实现依赖管理的意义 我们已经通过大量的例子说明了依赖管理的作用。总结起来&#xff0c;依赖管理不仅要检查项目中声明的直接依赖之间的冲突&#xff0c;还要检查它们各自的传递依赖之间的彼此兼容性。 Poetry 进行依赖管理的相关命令 在 Poetry 管理的工程中&am…

基于电商场景的高并发RocketMQ实战-Commitlog基于内存的高并发写入优化、基于JVM offheap的内存读写分离机制

&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308; 【11来了】文章导读地址&#xff1a;点击查看文章导读&#xff01; &#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f341;&#x1f3…

Flutter开发一个Wifi信号测量应用

在之前的一篇文章中我介绍了如何用Jetpack compose来开发一个Android的Wifi信号测量应用&#xff0c;使得可以根据室内不同地点的Wifi信号来生成指纹&#xff0c;用于室内导航&#xff0c;详情可见Jetpack Compose开发一个Android WiFi信号测量应用-CSDN博客。但是Jetpack comp…

【Hadoop】ZooKeeper数据模型Znode

ZooKeeper 数据模型ZnodeZooKeeper 中的时间ZooKeeper 节点属性 ZooKeeper 数据模型Znode 前面提过&#xff0c;Zookeeper相当于文件系统通知机制。既然是文件系统&#xff0c;那就涉及数据模型。 ZooKeeper 的数据模型在结构上和Unix标准文件系统非常相似&#xff0c;都是采用…

分类预测 | Matlab实现SCSO-SVM基于沙猫群优化算法优化支持向量机的多变量分类预测【23年新算法】

分类预测 | Matlab实现SCSO-SVM基于沙猫群优化算法优化支持向量机的多变量分类预测【23年新算法】 目录 分类预测 | Matlab实现SCSO-SVM基于沙猫群优化算法优化支持向量机的多变量分类预测【23年新算法】分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现SCSO-…

C# WPF上位机开发(windows pad上的应用)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 大部分同学可能都认为c# wpf只能用在pc端。其实这是一种误解。c# wpf固然暂时只能运行在windows平台上面&#xff0c;但是windows平台不仅仅是电脑…

听GPT 讲Rust源代码--src/tools(27)

File: rust/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs 文件rust/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs的作用是实施Clippy lint规则&#xff0c;检测产生潜在性能问题的字符转换代码&#xff0c;并给出相关建议。 在Rus…