蓝桥杯算法题-图形排版

news2024/11/26 2:51:58

题目描述

小明需要在一篇文档中加入 N 张图片,其中第 i 张图片的宽度是 Wi,高度是 Hi。
  假设纸张的宽度是 M,小明使用的文档编辑工具会用以下方式对图片进行自动排版:

1. 该工具会按照图片顺序,在宽度 M 以内,将尽可能多的图片排在一行。该行的高度是行内最高的图片的高度。例如在 M=10 的纸张上依次打印 3x4, 2x2, 3x3 三张图片,则效果如下图所示,这一行高度为4。(分割线以上为列标尺,分割线以下为排版区域;数字组成的矩形为第x张图片占用的版面)
 
2. 如果当前行剩余宽度大于0,并且小于下一张图片,则下一张图片会按比例缩放到宽度为当前行剩余宽度(高度向上取整),然后放入当前行。例如再放入一张4x9的图片,由于剩余宽度是2,这张图片会被压缩到2x5,再被放入第一行的末尾。此时该行高度为5:

3. 如果当前行剩余宽度为0,该工具会从下一行开始继续对剩余的图片进行排版,直到所有图片都处理完毕。此时所有行的总高度和就是这 N 张图片的排版高度。例如再放入11x1, 5x5, 3x4 的图片后,效果如下图所示,总高度为11:


现在由于排版高度过高,图片的先后顺序也不能改变,小明只好从 N 张图片中选择一张删除掉以降低总高度。他希望剩余N-1张图片按原顺序的排版高度最低,你能求出最低高度是多少么?

输入:
第一行包含两个整数 M 和 N,分别表示纸张宽度和图片的数量。
  接下来 N 行,每行2个整数Wi, Hi,表示第 i 个图大小为 Wi*Hi。

对于30%的数据,满足1<=N<=1000
  对于100%的数据,满足1<=N<=100000,1<=M, Wi, Hi<=100

输出:
一个整数,表示在删除掉某一张图片之后,排版高度最少能是多少。

样例输入1:
4 3
2 2
2 3
2 2
样例输出1:
2
 

 思路:要删去一张图片,使高度最小,无非是遍历N张图片,判断第i个图片不选是否拥有更小的高度。

可以分割一下状态,例如第i行中图片j,判断不选图片j的高度,可以由三个状态组成:

①前i-1行的总高度,这是固定的,在遍历过程就可以知道;

②i+1行以后的总高度,这个要怎么得到呢,可以知道,i+1行开头肯定是新的照片k,我从那张照片k开始遍历到最后一张照片,所得的高度一定是确定的,可以设置一个数组t[i]保留i照片以及以后的高度。

③此时不选j,第i行的高度,想要求这个可以定义一个calc函数,实现向行中添加图片,直到添加完全部图片或者宽度已达最大,求出该行的高度(再加上t[i]就成了第i行以及以后所有行的总高度),为了实现calc函数,还得定义一个solve函数,solve函数的目的是判断加了一张图片,该行的宽度和高度变化。

很明显用了动态规划的思想,他有状态转移关系,问题被细分为了多个子问题,把处理全部细分为了处理行。

这种方法适用于一些题目,题目中总体只修改了部分结构,只需要处理那部分被修改的状态,其余的部分可以通过处理得到,视为常量。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int m,n,h[N],w[N],t[N];
void solve(int i,int& W,int& H){
	if(W+w[i]<=m){ 
		H=max(H,h[i]); 
	}else{
		H=max(H,(h[i]*(m-W)+w[i]-1)/w[i]);
	}
	W=min(m,W+w[i]);
} 
int calc(int i,int W,int H){
	while(i<n&&W<m)solve(i++,W,H); 
	return H+t[i];
}
int main(){
	cin>>m>>n;
	for(int i=0;i<n;i++)cin>>w[i]>>h[i];
	for(int i=n-1;i>=0;i--)t[i]=calc(i,0,0);
	int res=t[0],pre_h=0,W=0,H=0;
	for(int i=0;i<n;i++){
		int tmp=calc(i+1,W,H);
		res=min(res,pre_h+tmp);
		solve(i,W,H);
		if(W==m)pre_h+=H,W=0,H=0;
	} 
	cout<<res<<endl;
} 

加了注释后: 

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int m,n,h[N],w[N],t[N];//m为每行最大宽度,n为图片数量,h为每张图片对应高度,w为每张图片对应宽度,t[i]为以i图片为开始,与他以后所有的图片组合,形成的最小高度(一定是以i为行头开始)
void solve(int i,int& W,int& H){//找出加入i元素后,该行的高度和宽度所发生的变化 
	if(W+w[i]<=m){//没超出最大宽度 
		H=max(H,h[i]); 
	}else{
		H=max(H,(h[i]*(m-W)+w[i]-1)/w[i]);//为什么要加w[i]-1,因为他要向上取整,所以要加一个小数,即(w[i]-1)/w[i]
	}
	W=min(m,W+w[i]);
} 
int calc(int i,int W,int H){//求出加入i以及他后边所有图片后,总高度的变化 
	while(i<n&&W<m)solve(i++,W,H);//只要算一行的,另起一行的可以直接由t[i]得到 
	return H+t[i];//为什么这里是H+t[i],因为之前的一行可能已经有照片了,我先填满那一行,拿到那一行的高度即H,然后之后的元素就另起一行了,对应t[i],所以t[i]是需要预处理的,所以总的高度为H+t[i] 
}
int main(){
	cin>>m>>n;
	for(int i=0;i<n;i++)cin>>w[i]>>h[i];
	for(int i=n-1;i>=0;i--)t[i]=calc(i,0,0);//W=0,H=0,说明要求的是以i照片开头的,与它以后所有的图片组合形成的最小高度,预处理阶段,不预处理,以后可能有重复的求解过程
	int res=t[0],pre_h=0,W=0,H=0;//res先取t[0],是代表所有图片都取了后它的高度, pre_h为 之前已经统计了的行的高度,正在统计的不算 
	for(int i=0;i<n;i++){
		int tmp=calc(i+1,W,H);//计算出加入i+1以及之后的所有图片后,总高度的变化,不包括i,这就对应了删除一张图片的思想 
		res=min(res,pre_h+tmp);//前者为之前统计出的最小高度,后者为不要i照片的最小高度 
		solve(i,W,H);//加入i照片
		if(W==m)pre_h+=H,W=0,H=0;//此时已经充满一行,那就得另起一行了,所以pre_h要+H,H和W要清零 
	} 
	cout<<res<<endl;
} 

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

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

相关文章

LabVIEW转动设备故障诊断系统

LabVIEW转动设备故障诊断系统 随着工业自动化技术的不断进步&#xff0c;转动设备在电力、化工、船舶等多个行业中扮演着越来越重要的角色。然而&#xff0c;这些设备在长期运行过程中难免会出现故障&#xff0c;如果不能及时诊断和处理&#xff0c;将会导致生产效率下降&…

【JavaSE】一维数组和二维数组详解

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 一维数组 基本语法 初始化 遍历和打印 数组是引用型变量 基本类型变量与引用类型变量的区别 null 数组传参和返回 总结 二维数组 基本语法 初始化 遍历和打印 一维数组…

排序——非基于比较的排序

本专栏和大家分享关于排序的算法,其中有插入排&#xff08;直接插入排序和希尔排序&#xff09;、选择排序&#xff08;直接选择排序和堆排&#xff09;、交换排序&#xff08;冒泡排序和快速排序&#xff09;、归并排序以及其他非基于比较的排序 本文与大家分享非基于比较的排…

透视未来安全:PIR技术引领数据隐私新时代

1.隐语实现PIR总体介绍 隐语实现的Private Information Retrieval (PIR) 是一种隐私增强技术&#xff0c;它使用户能够在不暴露他们实际查询内容的情况下从远程服务器数据库中检索所需信息。以下是隐语在实现PIR方面的概要说明和技术特点&#xff1a; 基本概念&#xff1a; PI…

移动硬盘无法读取打不开?原因分析与解决方案

一、移动硬盘遭遇困境&#xff1a;无法读取打不开 在数字信息爆炸的时代&#xff0c;移动硬盘成为了我们储存和传输数据的重要工具。然而&#xff0c;当移动硬盘突然无法读取打不开时&#xff0c;我们往往会感到手足无措。插入电脑后&#xff0c;移动硬盘的指示灯可能正常闪烁…

算法系列--动态规划--特殊的状态表示--分析重复子问题

&#x1f495;"轻舟已过万重山!"&#x1f495; 作者&#xff1a;Lvzi 文章主要内容&#xff1a;算法系列–算法系列–动态规划–特殊的状态表示–分析重复子问题 大家好,今天为大家带来的是算法系列--动态规划--特殊的状态表示--分析重复子问题 一.组合总数IV 链接…

dubbo下

dubbo 集成springboot 配置文件 controller 启动类 注册中心宕机 负载均衡 zookeeper注册中心 dubbo原理 dubbo架构 各层说明 增强spi原理

Native Instruments Kontakt 7 for Mac v7.9.0 专业音频采样

Native Instruments Kontakt 7是一款强大的软件采样器&#xff0c;它允许用户从各种来源采样音频并进行编辑和处理。它包含大量预设采样库&#xff0c;包括乐器、合成器、鼓组和声音效果等。此外&#xff0c;Kontakt 7还允许用户创建自己的采样库&#xff0c;以便根据自己的需要…

2-Prometheus监控主机

1 介绍 Prometheus 使用 node_exporter 服务程序监控 Linux 主机。 2 部署 2.1 下载 官方下载地址 https://prometheus.io/download/ 找到 node-export 下载即可 curl -o node-exporter.tar.gz -L https://github.com/prometheus/node_exporter/releases/download/v1.7.0/…

Linux非root用户安装mysql5.7

1、下载安装包MySQL :: Download MySQL Community Server 点击Archives 我下载的是5.7.27版本&#xff0c;linux主机直接选择linux-Generic即可&#xff0c;选择第一个包下载即可 2、安装mysql 解压 shell> tar xzvf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz shell&g…

idea中Git项目遇到“Filename too long”错误 与 配置Git的ssh证书

一&#xff1a;“Filename too long”问题解决办法 错误信息&#xff1a; fatal: cannot create directory at xxxx: Filename too long warning: Clone succeeded, but checkout failed. You can inspect what was checked out with git status and retry with git restore …

【Visual Studio】将项目下的文件夹所有文件随编译自动复制输出到运行目录

要将项目根目录下的文件夹内容输出到运行目录&#xff0c;去处理其中的子文件夹和文件&#xff0c;逐个手动设置文件属性或进行复制显然不是一个可行的方法&#xff0c;因为这既繁琐又低效&#xff0c;那有没有更加高效的方式呢 文章目录 选择文件夹修改配置文件输出文件夹 这里…

二维码门楼牌管理应用平台建设:实现民主参与的新途径

文章目录 前言一、二维码门楼牌管理应用平台的兴起二、投票表决功能的实现三、居民参与度的提升四、面临的挑战与前景展望 前言 在数字化时代&#xff0c;二维码技术的应用已经渗透到我们生活的方方面面。近期&#xff0c;二维码门楼牌管理应用平台的建设成为了社区治理的一大…

Android设备无线连接电脑及QXDM、QACT等工具的方法

首先样机和笔记本电脑连接同一wifi网络 adb root adb shell ifconfig复制inet addr地址 ping inet addr地址 adb tcpip 5555 adb connect (inet addr地址):5555 此时adb和机器使用wifi连接好了&#xff0c;可以拔出usb线 ipconfig查询电脑的IP地址 ipconfig使用adb在主机上…

Qt使用opencv,进行视频录制,功能打开、关闭摄像头,开始、结束录制视频,暂停、继续录制,并保存视频文件

1.效果图 2 代码实现 2.1 .h文件 #ifndef VIDEORECORDWIDGET_H #define VIDEORECORDWIDGET_H#include <QWidget>#include<QFileDialog>#include <QImage> #include <QLabel> #include <QTimer> #include <opencv2/opencv.hpp>using name…

pytest--python的一种测试框架--fixture/YAML/parametrize

一、pytest的fixture详解 fixture概念fixture是pytest用于将测试前后进行预备、清理工作的代码处理机制。 fixture相对于setup和steardown来说有以下几个优势&#xff1a; 1.fixure命名更加灵活&#xff0c;局限性比较小。 2.conftest.py配置里面可以实现数据共享&#xff0…

数据可视化-Python

师从黑马程序员 Json的应用 Json的概念 Json的作用 Json格式数据转化 Python数据和Json数据的相互转化 注&#xff1a;把字典列表变为字符串用dumps,把字符串还原回字典或列表用loads import json#准备列表&#xff0c;列表内每一个元素都是字典&#xff0c;将其转化为Json …

【Clang+LLVM+honggfuzz学习】(一)LLVM简介、安装和第一个Hello Pass

本文结构&#xff0c;PS:根据需要选择观看哦 1. 前言参考 2.简介传统编译器架构LLVM架构 3. LLVM安装版本准备官网源码下载git下载安装过程 4. 写一个LLVM Pass旧Hello Pass实现&#xff08;legacy PM version&#xff09;新Hello Pass实现&#xff08;Using the New Pass Mana…

第六十三回 呼延灼月夜赚关胜 宋公明雪天擒索超-大模型BERT、ERNIE、GPT和GLM的前世今生

神行太保戴宗报信&#xff0c;关胜人马直奔梁上泊&#xff0c;请宋江早早收兵&#xff0c;解梁山之难。宋江派了花荣到飞虎峪左边埋伏&#xff0c;林冲到右边埋伏&#xff0c;再叫呼延灼带着凌振&#xff0c;在离城十里附近布置了火炮&#xff0c;然后才令大军撤退。 李成闻达…

典型周边生态系统

目录 一、概述 二、项目管理系统 2.1 项目管理系统基本工作流 2.2 常用项目管理系统介绍 2.2.1 禅道 2.2.1.1 禅道概述 2.2.1.2 禅道特点 2.2.1.2.1 部署方案 2.2.1.2.2 管理模型 2.2.1.2.3 DevOps解决方案 2.2.1.2.4 自动化测试 2.2.1.2.5 数据大屏 2.2.1.2.6 协同…