2023-01-14:给定一个二维数组map,代表一个餐厅,其中只有0、1两种值 map[i][j] == 0 表示(i,j)位置是空座 map[i][j] == 1 表示(i,j)位置坐了人 根据防
2023-01-14:给定一个二维数组map,代表一个餐厅,其中只有0、1两种值
map[i][j] == 0 表示(i,j)位置是空座
map[i][j] == 1 表示(i,j)位置坐了人
根据防疫要求,任何人的上、下、左、右,四个相邻的方向都不能再坐人
但是为了餐厅利用的最大化,也许还能在不违反防疫要求的情况下,继续安排人吃饭
请返回还能安排的最大人数
如果一开始的状况已经不合法,直接返回-1
比如:
1 0 0 0
0 0 0 1
不违反防疫要求的情况下,这个餐厅最多还能安排2人,如下所示,X是新安排的人
1 0 X 0
0 X 0 1
再比如:
1 0 0 0 0 1
0 0 0 0 0 0
0 1 0 0 0 1
0 0 0 0 0 0
不违反防疫要求的情况下,这个餐厅最多还能安排7人,如下所示,X是新安排的人
1 0 0 X 0 1
0 0 X 0 X 0
0 1 0 X 0 1
X 0 X 0 X 0
数据范围 : 1 <= 矩阵的行、列 <= 20
来自华为。
答案2023-01-14:
轮廓线dp。
代码用solidity和rust编写。
代码用solidity编写。代码如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract Hello{
function main() public pure returns (int32){
int32[][] memory matrix = new int32[][](2);
for (int32 i = 0; i < 2; i++) {
matrix[uint32(i)] = new int32[](2);
for (int32 j = 0; j < 2; j++) {
matrix[uint32(i)][uint32(j)] = 0;
}
}
//matrix[1][1] = 1;
int32 ans = mostSeats2(matrix);
return ans;
}
// 正式方法
// 轮廓线dp
function mostSeats2(int32[][] memory map) public pure returns(int32){
int32 n = int32(int(map.length));
int32 m = int32(int(map[0].length));
int32[] memory arr = new int32[](uint32(n));
for (int32 i = 0; i < n; i++) {
int32 status = 0;
for (int32 j = 0; j < m; j++) {
if (map[uint32(i)][uint32(j)] == 1) {
if (i > 0 && map[uint32(i - 1)][uint32(j)] == 1) {
return -1;
}
if (j > 0 && map[uint32(i)][uint32(j - 1)] == 1) {
return -1;
}
}
status |= map[uint32(i)][uint32(j)] *leftk(j);
}
arr[uint32(i)] = status;
}
int32 s = leftk(m);
int32[][][] memory dp = new int32[][][](uint32(n));
for (int32 i = 0; i < n; i++) {
dp[uint32(i)] = new int32[][](uint32(m));
for (int32 j = 0; j < m; j++) {
dp[uint32(i)][uint32(j)] = new int32[](uint32(s));
for (int32 k = 0; k < s; k++) {
dp[uint32(i)][uint32(j)][uint32(k)] = -2;
}
}
}
int32 ans = process2(arr, n, m, 0, 0, 0, dp);
return ans == -1 ? int32(0) : ans;
}
// 20 * 20 * 2^20 -> 4 * 10^8
function process2(int32[] memory arr, int32 n, int32 m, int32 i, int32 j, int32 status, int32[][][] memory dp) public pure returns (int32){
if (j == m) {
return process2(arr, n, m, i + 1, 0, status, dp);
}
if (i == n) {
return 0;
}
if (dp[uint32(i)][uint32(j)][uint32(status)] != -2) {
return dp[uint32(i)][uint32(j)][uint32(status)];
}
A memory a = A(0,0,0,0,0,0,0);
a.left = status0(status, j - 1, m);
a.up = status0(status, j, m);
a.cur = status0(arr[uint32(i)], j, m);
a.right = status0(arr[uint32(i)], j + 1, m);
if (a.up == 1 && a.cur == 1) {
return -1;
}
a.p1 = -1;
if (a.cur == 1) {
a.p1 = process2(arr, n, m, i, j + 1, status | leftk(j), dp);
} else {
a.p1 = process2(arr, n, m, i, j + 1, (status | leftk(j)) ^ leftk(j), dp);
}
a.p2 = -1;
if (a.left == 0 && a.up == 0 && a.cur == 0 && a.right == 0) {
int32 next2 = process2(arr, n, m, i, j + 1, status | leftk(j), dp);
if (next2 != -1) {
a.p2 = 1 + next2;
}
}
a.ans = max(a.p1, a.p2);
dp[uint32(i)][uint32(j)][uint32(status)] = a.ans;
return a.ans;
}
function status0(int32 status, int32 i, int32 m)public pure returns (int32) {
return (i < 0 || i == m || (status & (leftk(i))) == 0) ? int32(0) : int32(1);
}
function leftk(int32 k) public pure returns (int32){
int32 ans = 1;
while (k>0){
ans*=2;
k--;
}
return ans;
}
function max(int32 a,int32 b)public pure returns (int32){
if(a>b){
return a;
}else{
return b;
}
}
}
// 局部变量超过了16个,需要用结构体封装
struct A{
int32 left;
int32 up;
int32 cur;
int32 right;
int32 p1;
int32 p2;
int32 ans;
}

代码用rust编写。代码如下:
use rand::Rng;
use std::iter::repeat;
fn main() {
let mut matrix = vec![vec![0, 0], vec![0, 0]];
let ans3 = most_seats2(&mut matrix);
println!("ans3 = {}", ans3);
let nn: i32 = 10;
let mm: i32 = 10;
let one_p = 15;
let test_time: i32 = 10000;
println!("测试开始");
for i in 0..test_time {
let n = rand::thread_rng().gen_range(0, nn) + 1;
let m = rand::thread_rng().gen_range(0, mm) + 1;
let mut matrix = random_matrix(n, m, one_p);
let ans1 = most_seats1(&mut matrix);
let ans2 = most_seats2(&mut matrix);
if ans1 != ans2 {
println!("出错了!{}", i);
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
break;
}
}
println!("测试结束");
}
// 为了测试,普通方法
// 普通的状态压缩动态规划
// 每一行用dfs的方法
// 体系学习班,章节44 : 状态压缩的动态规划,贴瓷砖问题类似
fn most_seats1(map: &mut Vec<Vec<i32>>) -> i32 {
let n = map.len() as i32;
let m = map[0].len() as i32;
let mut arr: Vec<i32> = repeat(0).take(n as usize).collect();
for row in 0..n {
let mut status = 0;
let mut col = 0;
let mut i = m - 1;
while col < m {
if map[row as usize][col as usize] == 1 {
if row > 0 && map[(row - 1) as usize][col as usize] == 1 {
return -1;
}
if col > 0 && map[row as usize][(col - 1) as usize] == 1 {
return -1;
}
}
status |= map[row as usize][col as usize] << i;
col += 1;
i -= 1;
}
arr[row as usize] = status;
}
let mut dp: Vec<Vec<i32>> = repeat(repeat(-2).take((1 << m) as usize).collect())
.take(n as usize)
.collect();
let ans = process1(&mut arr, 0, 0, m, &mut dp);
return if ans == -1 { 0 } else { ans };
}
fn process1(arr: &mut Vec<i32>, row: i32, pre: i32, m: i32, dp: &mut Vec<Vec<i32>>) -> i32 {
if row == arr.len() as i32 {
return 0;
}
if dp[row as usize][pre as usize] != -2 {
return dp[row as usize][pre as usize];
}
let cur = arr[row as usize];
let mut ans = 0;
if (cur & pre) != 0 {
ans = -1;
} else {
ans = dfs(arr, row, m - 1, pre, cur, m, dp);
}
dp[row as usize][pre as usize] = ans;
return ans;
}
fn dfs(
arr: &mut Vec<i32>,
row: i32,
col: i32,
pre: i32,
seats: i32,
m: i32,
dp: &mut Vec<Vec<i32>>,
) -> i32 {
if col == -1 {
return process1(arr, row + 1, seats, m, dp);
} else {
let p1 = dfs(arr, row, col - 1, pre, seats, m, dp);
let mut p2 = -1;
if (pre & (1 << col)) == 0
&& (seats & (1 << col)) == 0
&& (col == m - 1 || (seats & (1 << (col + 1))) == 0)
&& (col == 0 || (seats & (1 << (col - 1))) == 0)
{
let next2 = dfs(arr, row, col - 1, pre, seats | (1 << col), m, dp);
if next2 != -1 {
p2 = 1 + next2;
}
}
return get_max(p1, p2);
}
}
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
}
// 正式方法
// 轮廓线dp
fn most_seats2(map: &mut Vec<Vec<i32>>) -> i32 {
let n = map.len() as i32;
let m = map[0].len() as i32;
let mut arr: Vec<i32> = repeat(0).take(n as usize).collect();
for i in 0..n {
let mut status = 0;
for j in 0..m {
if map[i as usize][j as usize] == 1 {
if i > 0 && map[(i - 1) as usize][j as usize] == 1 {
return -1;
}
if j > 0 && map[i as usize][(j - 1) as usize] == 1 {
return -1;
}
}
status |= map[i as usize][j as usize] << j;
}
arr[i as usize] = status;
}
let s = 1 << m;
let mut dp: Vec<Vec<Vec<i32>>> = repeat(
repeat(repeat(-2).take(s as usize).collect())
.take(m as usize)
.collect(),
)
.take(n as usize)
.collect();
let ans = process2(&mut arr, n, m, 0, 0, 0, &mut dp);
return if ans == -1 { 0 } else { ans };
}
// 20 * 20 * 2^20 -> 4 * 10^8
fn process2(
arr: &mut Vec<i32>,
n: i32,
m: i32,
i: i32,
j: i32,
status: i32,
dp: &mut Vec<Vec<Vec<i32>>>,
) -> i32 {
if j == m {
return process2(arr, n, m, i + 1, 0, status, dp);
}
if i == n {
return 0;
}
if dp[i as usize][j as usize][status as usize] != -2 {
return dp[i as usize][j as usize][status as usize];
}
let left = status0(status, j - 1, m);
let up = status0(status, j, m);
let cur = status0(arr[i as usize], j, m);
let right = status0(arr[i as usize], j + 1, m);
if up == 1 && cur == 1 {
return -1;
}
let mut p1 = -1;
if cur == 1 {
p1 = process2(arr, n, m, i, j + 1, status | (1 << j), dp);
} else {
p1 = process2(arr, n, m, i, j + 1, (status | (1 << j)) ^ (1 << j), dp);
}
let mut p2 = -1;
if left == 0 && up == 0 && cur == 0 && right == 0 {
let next2 = process2(arr, n, m, i, j + 1, status | (1 << j), dp);
if next2 != -1 {
p2 = 1 + next2;
}
}
let ans = get_max(p1, p2);
dp[i as usize][j as usize][status as usize] = ans;
return ans;
}
fn status0(status: i32, i: i32, m: i32) -> i32 {
return if i < 0 || i == m || (status & (1 << i)) == 0 {
0
} else {
1
};
}
fn random_matrix(n: i32, m: i32, p0: i32) -> Vec<Vec<i32>> {
let mut ans: Vec<Vec<i32>> = repeat(repeat(0).take(m as usize).collect())
.take(n as usize)
.collect();
for i in 0..n {
for j in 0..m {
ans[i as usize][j as usize] = if rand::thread_rng().gen_range(0, 100) < p0 {
1
} else {
0
};
}
}
return ans;
}

2023-01-14:给定一个二维数组map,代表一个餐厅,其中只有0、1两种值 map[i][j] == 0 表示(i,j)位置是空座 map[i][j] == 1 表示(i,j)位置坐了人 根据防的更多相关文章
- PHP如何随机获取一个二维数组中的一个值
获取一个数组: $awardid_list=pdo_fetchall('select id from '.tablename($this->table_award)); 这是微擎的写法哈,意思就 ...
- ytu 1050:写一个函数,使给定的一个二维数组(3×3)转置,即行列互换(水题)
1050: 写一个函数,使给定的一个二维数组(3×3)转置,即行列互换 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 154 Solved: 112[ ...
- [CareerCup] 13.10 Allocate a 2D Array 分配一个二维数组
13.10 Write a function in C called my2DAlloc which allocates a two-dimensional array. Minimize the n ...
- new一个二维数组
.定义一个二维数组 char **array1 array1 = new char *[x]; for(i=0;i<x;++i) array1[i] = new char[y]; ...用的时候 ...
- c语言题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点
//题目:找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小.也可能没有鞍点. // #include "stdio.h" #include <stdli ...
- JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数
JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数 示例如下 至少需要九个元素:"A","B","C",&q ...
- C语言程序,找出一个二维数组的鞍点。
什么是鞍点????? 鞍点就是在一个二维数组中,某一个数在该行中最大,然而其在该列中又是最小的数,这样的数称为鞍点. 昨天突然在书上看到这样的一道题,就自己尝试着写了一个找出一个二维数组中的鞍点. 好 ...
- C#编写程序,找一找一个二维数组中的鞍点
编写程序,找一找一个二维数组中的鞍点(即该位置上的元素值在行中最大,在该列上最小.有可能数组没有鞍点).要求: 1.二维数组的大小.数组元素的值在运行时输入: 2.程序有友好的提示信息. 代码: us ...
- php中向前台js中传送一个二维数组
在php中向前台js中传送一个二维数组,并在前台js接收获取其中值的全过程方法: (1),方法说明:现在后台将数组发送到前台 echo json_encode($result); 然后再在js页面中的 ...
- 如何用一个for循环打印出一个二维数组
思路分析: 二维数组在内存中默认是按照行存储的,比如一个二维数组{{1,2,3,},{4,5,6}},它在内存中存储的顺序就是1.2.3.4.5.6,也就是说,对于这6个数组元素,按照从0到5给它们编 ...
随机推荐
- vue下拉选择select option el-cascader删除重选值的问题
select当下拉值多的时候 以及input cascader级联选择一个值后 后面我不想要了 vue 提供了一个关键字 可以帮你全部清空 这个关键字就是:clearable
- BitBake使用攻略--BitBake的语法知识二
目录 写在前面 1. BitBake中的任务 2. 任务配置 2.1 依赖 2.1.1 内部任务间的依赖 2.1.2 不同菜谱下的任务间依赖 2.1.3 运行时态下的依赖 2.1.4 递归依赖 2.1 ...
- 微软NewBing真是Niubility
这是本人2012年的拙作: 晨兮,闻风雨,后而雷鸣电闪.迟不可再三,若故无食.然何如耶?雨大风狂,单车奈何?公交卡空,恐时不予我也.不免叹也,天亦不予我! 而后出, ...
- Android进度表示
在连接上数据库之后,一切都变得简单了呢! 开心,很轻松地就能够将APP里面的相关内容写完啦! 尝试了好久的连接Mysql数据库,最后还是没有成功: 虽然Android studio里面自带的SQLit ...
- Axios的相关应用
Axios 的案例应用 要求利用axios实现之前利用AJAX实现的验证用户是否登录的案例 鉴于这两种语法的相似性,只需要在AJAX里面的注册界面里面的script标签里面包含的代码修改为如下代码即可 ...
- 震惊,一行MD5居然让小伙伴都回不了家!!!
作者:京东零售 付伟 1. 前言 大家好,当你点开这篇文章的时候也许心想是哪个 XX 小编混到这里,先不要着急扔臭鸡蛋,本文是一篇标准(正经)的问题复盘文章.好了,一行MD5居然让小伙伴下不了班,到底 ...
- TCP 三次握手,给我长脸了噢
大家好,我是小富~ 个人资源分享网站:FIRE 本文收录在 Springboot-Notebook 面试锦集 前言 之前有个小伙伴在技术交流群里咨询过一个问题,我当时还给提供了点排查思路,是个典型的八 ...
- RTE NG-Lab:一起探索下一代实时互动新世界
互联网已经彻底改变了我们的工作和生活.从纸书信笺,到智能手机中的 App,再到 VR 头显,实时互动体验逐代升级,已经成为了我们生活的一部分.随着元宇宙的爆火,新增的实时互动场景日益颠覆着我们的想象力 ...
- fullcalendar 日历插件的使用
[需求]:使用 fullcalendar日历插件,完成如下功能:可以进行拖动,点击空白处添加,双击后修改和删除等功能.API 链接
- Troubleshooting 专题 - 问正确的问题 得到正确的答案
在很多公司中,IT.数据中心.业务系统一出故障,会有很多人被叫到作战室(就是一个为了解决该问题,而把所有相关人员集中在一起的一个会议室), 但是对于这个问题他们是否可以修复, 是否他们应该负有责任, ...