首页 > 其他分享 >2024/7/14 每日一题 + 周赛P3/P4

2024/7/14 每日一题 + 周赛P3/P4

时间:2024-07-14 16:53:10浏览次数:8  
标签:P4 周赛 开销 14 天际线 int grid verticalCut horizontalCut

807. 保持城市天际线

问题描述


给你一座由 n x n 个街区组成的城市,每个街区都包含一座立方体建筑。给你一个下标从 0 开始的 n x n 整数矩阵 grid ,其中 grid[r][c] 表示坐落于 rc 列的建筑物的 高度 。

城市的 天际线 是从远处观察城市时,所有建筑物形成的外部轮廓。从东、南、西、北四个主要方向观测到的 天际线 可能不同。

我们被允许为 任意数量的建筑物 的高度增加 任意增量(不同建筑物的增量可能不同)。 高度为 0 的建筑物的高度也可以增加。然而,增加的建筑物高度 不能影响 从任何主要方向观察城市得到的 天际线 。

在 不改变 从任何主要方向观测到的城市 天际线 的前提下,返回建筑物可以增加的 最大高度增量总和 。


img

输入:grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]
输出:35
解释:建筑物的高度如上图中心所示。
用红色绘制从不同方向观看得到的天际线。
在不影响天际线的情况下,增加建筑物的高度:
gridNew = [ [8, 4, 8, 7],
              [7, 4, 7, 7],
              [9, 4, 8, 7],
              [3, 3, 3, 3] ]

思路

我们可以想到 NorthSouthWestEast 方向看到的天际线应该是相同的高度,相反的顺序(从左至右、从右至左)。对于 grid 数组中的任意一个元素 grid[i][j] 其增量取决于第 i 行和第 j 列中的两个最大值中的最小值。

例如考虑 grid[0][0],第 0 行的最大值为 8,第 0 列的最大值为 9,其余值不影响天际线的高度,因此我们只需要考虑在增加了增量后不超过这两个天际线的高度(不产生视图的变化)。那么我们就可以得到一个贪心的逻辑:

  • 维护两个行列数组,记录对应行/列中的最大值。

  • 把 grid 数组中的元素其两个数组中对应的行列进行比较,选择两值中较小的值作为天际线的位置,增量的值就是天际线的位置减去 grid 数组中当前元素的高度。

代码实现

class Solution {
public:
    int maxIncreaseKeepingSkyline(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        vector<int> maxRaw(m, 0);
        vector<int> maxCol(n, 0);
        
        for (int raw = 0; raw < m; raw++) {
            for (int col = 0; col < n; col++) {
                /** 记录竖向遍历中,每一行的最大值, raw 是不变量 */
                maxRaw[raw] = max(maxRaw[raw], grid[raw][col]);
                /** 记录横向遍历中,每一列的最大值,col 是变量 */
                maxCol[col] = max(maxCol[col], grid[raw][col]);
            }
        }
        int result = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                result +=  min(maxRaw[i], maxCol[j]) - grid[i][j];
            }
        }
        return result;
    }
};

切蛋糕的最小总开销

题目描述

有一个 m x n 大小的矩形蛋糕,需要切成 1 x 1 的小块。

给你整数 m ,n 和两个数组:

  • horizontalCut 的大小为 m - 1 ,其中 horizontalCut[i] 表示沿着水平线 i 切蛋糕的开销。

  • verticalCut 的大小为 n - 1 ,其中 verticalCut[j] 表示沿着垂直线 j 切蛋糕的开销。

一次操作中,你可以选择任意不是 1 x 1 大小的矩形蛋糕并执行以下操作之一:

  1. 沿着水平线 i 切开蛋糕,开销为 horizontalCut[i]

  2. 沿着垂直线 j 切开蛋糕,开销为 verticalCut[j]

每次操作后,这块蛋糕都被切成两个独立的小蛋糕。

每次操作的开销都为最开始对应切割线的开销,并且不会改变。

请你返回将蛋糕全部切成 1 x 1 的蛋糕块的 最小 总开销。


思路

首先,每条水平线和垂直线,最终都要全部切完。

  • 水平线(横切)开销 horizontalCut[i] 对答案的贡献,等于 horizontalCut[i] 乘以在此之前竖切的次数加一。

  • 垂直线(竖切)开销 verticalCut[j] 对答案的贡献,等于 verticalCut[j] 乘以在此之前横切的次数加一。

对于一个操作序列,交换其中两个相邻的横切,不影响答案;交换其中两个相邻的竖切,也不影响答案。所以重点考察交换两个相邻的横切和竖切。

设横切的开销为 h,在此之前竖切的次数加一为 cntV;设竖切的开销为 v,在此之前横切的次数加一为 cntH。

  • 先横切,再竖切,开销为 h⋅cntV+v⋅(cntH+1)

  • 先竖切,再横切,开销为 v⋅cntH+h⋅(cntV+1)

如果先横再竖开销更小,则有


h⋅cntV+v⋅(cntH+1) < v⋅cntH+h⋅(cntV+1)


化简得:h>v

这意味着,谁的开销更大,就先切谁,并且操作顺序与 cntH 和 cntV 无关。按照该规则去切蛋糕,得到的操作序列,如果把开销大的操作移动后面,必然会得到更大的总开销。


代码实现

class Solution {
public:
    long long minimumCost(int m, int n, vector<int>& horizontalCut, vector<int>& verticalCut) {
        sort(horizontalCut.begin(), horizontalCut.end(), greater<int>());
        sort(verticalCut.begin(), verticalCut.end(), greater<int>());

        long long cost = 0;
        int rowIndex = 0, colIndex = 0;
        /** 横切和竖切的刀数*/
        int rowCnt = 1, colCnt = 1;
        while (rowIndex < m - 1 && colIndex < n - 1) {
            /** 贪心——>选择代价最大的切法能够减少开销 */
            if (horizontalCut[rowIndex] > verticalCut[colIndex]) {
                /** cost = Σ(cost/cut * cnt) */
                cost += horizontalCut[rowIndex++] * rowCnt;
                colCnt++;
            } else {
                cost += verticalCut[colIndex++] * colCnt;
                rowCnt++;
            }
        }

        /** 结束最小开销计算,现在计算总开销 */
        for (int i = rowIndex; i < m - 1; i++) {
            cost += horizontalCut[i] * rowCnt;
        }
        for (int j = colIndex; j < n - 1; j++) {
            cost += verticalCut[j] * colCnt;
        }

        return cost;
    }
};

总结

今天主要学习了贪心算法的二维运算逻辑,不论是天际线问题还是切蛋糕问题,都需要很好的理解行 row 和列 col 之间的关系,遍历的顺序和逻辑对结果的影响非常大。

标签:P4,周赛,开销,14,天际线,int,grid,verticalCut,horizontalCut
From: https://www.cnblogs.com/kristen-heu/p/18301669

相关文章

  • JDK14新特征最全详解
    JDK14一共发行了16个JEP(JDKEnhancementProposals,JDK增强提案),筛选出JDK14新特性。-343:打包工具(Incubator)-345:G1的NUMA内存分配优化-349:JFR事件流-352:非原子性的字节缓冲区映射-358:友好的空指针异常-359:Records(预览)-361:Switch表达式(标准......
  • Android 14.0 Camera2 静音时拍照去掉快门声音
    1.概述在14.0系统rom定制化开发时,在Camera2静音情况下有快门拍照声音,这就不符合使用规范了静音的情况下拍照也不应该发出声音,所以在静音拍照流程中要求去掉快门声音,接下来具体实现相关的功能2.Camera2静音拍照去掉快门声音核心代码/packages/apps/Camera2/src/co......
  • 2024 /7/14 H3U与MD600Modbus通讯应用指导
    目录步骤一:硬件接线步骤二:变频器参数设置步骤三:软件PLC程序配置 注意事项:步骤一:硬件接线                    PLC侧485端子                           MD600变频器侧......
  • LeetCode 144. 二叉树的前序遍历
    更多题解尽在https://sugar.matrixlab.dev/algorithm每日更新。组队打卡,更多解法等你一起来参与哦!LeetCode144.二叉树的前序遍历,难度中等。classSolution{publicvoidpreorderTraversal(TreeNoderoot,List<Integer>ans){if(root==null)re......
  • 基于Ubuntu 24.04 LTS安装elasticsearch-8.14.3+Kibanna
    1.安装Elasticsearch1.1下载Elasticsearch#1.更新包索引sudoaptupdate#2.升级已安装的软件包sudoaptupgrade-y#3.进入/opt目录cd/opt#4.下载Elasticsearch压缩包sudowgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8......
  • lgP4513 小白逛公园
    有n个公园,小白对第i个公园的评分为A[i],有m次操作:1ab表示在[a,b]范围内选择一段连续的公园遛狗;2ab表示小白对公园a的评分修改为b;对于操作1,输出可以取得的最大评分。分析:线段树维护区间子段和。#include<bits/stdc++.h>usingllong=longlong;constintinf=1e......
  • SP14887 GOODA - Good Travels 题解
    题目传送门前置知识Tarjan算法|最短路解法缩点后原图就成为了一个有向无环图,此时每个点最多被经过一次,故在求最长路的过程中可以将点权和边权混着转移。上篇题解用拓扑实现查找两点间最长路的做法正确性不会证,遂写了份Dijkstra求最长路。代码#include<bits/stdc++.h......
  • 怎样才能将MP4转换成RMVB格式?这五种视频格式转换法一定要知道
    在当今数字化时代,视频格式转换已成为许多人的日常需求。特别是将MP4格式的视频转换为RMVB格式,这在某些特定的播放环境或设备中显得尤为重要。本文将详细介绍几种将MP4转换成RMVB格式的方法,帮助读者轻松应对视频格式转换的问题。方法一:使用【汇帮视频格式转换器】操作步骤如下......
  • 【反悔贪心】P2949WorkSchedulingG+P4053[JSOI2007]建筑抢修题解
    这两天遇到了几个很神奇的题目——能反悔的贪心。赶紧记录一下。例1(用时一定模型)用时一定:每个任务完成的耗时都是一样的。题面:Luogu-P2949WorkSchedulingG大体思路是:先把所有任务按照截止时间从小到大排序,然后枚举,遇到一个能做任务的就把他做了,把他的贡献加入一个......
  • C++ //练习 14.44 编写一个简单的桌面计算器使其能处理二元运算。
    C++Primer(第5版)练习14.44练习14.44编写一个简单的桌面计算器使其能处理二元运算。环境:LinuxUbuntu(云服务器)工具:vim 代码块/************************************************************************* >FileName:ex14.44.cpp >Author: >Mail: >C......