OJ3829大石头的搬运工

题目:

在一款名为”大石头的搬运“的游戏中,玩家需要操作一排 n 堆石头,进行 n -1 轮游戏。每一轮,玩家可以选择一堆石头,并将其移动到任意位置。在n-1轮移动结束时,要求将所有的石头移动到一起(即所有石头的位置相同)即为成功。移动的费用为石头的重量乘以移动的距离。例如,如果一堆重量为2的石头从位置3移动到位置5,那么费用为 2x(5 -3)= 4。 请计算出所有合法方案中,将所有石头移动到一起的最小费用。 可能有多堆石头在同一个位置上,但是一轮只能选择移动其中一堆。

输入格式:

第一行一个整数 n,表示石头的数量。 接下来 几 行,每行两个整数 wi和 pi,分别表示第i个石头的重量和初始位置.

输出格式 :

输出一个整数,表示最小的总移动费用。

数据范围

对于 20%的测试样例,1<=n<=10^3。

对于100%的测试样例,1<=n<=10^5,1<=wi,pi<=10^6。

解题思路:


首先,我们需要明白在这个问题中,每一次移动的石头的位置并不影响后续的移动,也就是说,无论我们怎么移动石头,最后的总费用只依赖于每个石头最后的位置,而与移动的顺序无关。这个性质使得我们可以逐一考虑每个石头最后的位置,并比较得出最小的总费用。
然后,我们需要分析一下如何计算每一种放置石头的方式的总费用。一种直观的方法是,对于每个石头,我们都计算它被移动到目标位置的费用,然后将这些费用加总。但这样的计算方式在本题的数据范围下是无法接受的。我们需要寻找一种更优的方法。
这里,我们可以运用前缀和的思想。考虑到石头移动的费用与其重量和距离有关,我们可以先将石头按位置排序,然后计算每个石头移动到任一位置的费用,再利用前缀和的方法将这些费用累加起来。具体地,我们可以定义两个数组pre和nex,其中pre[i]表示前i个石头都移动到第i个石头的位置的总费用,nex[i]表示第i个石头之后的所有石头都移动到第i个石头的位置的总费用。这样,对于每个石头,我们就可以在0(1)的时间内算出所有石头都移动到它的位置的总费用。
时间复杂度分析
整个过程中,排序的时间复杂度是O(nlogn),计算pre和 nex的时间复杂度是O(n),查找pre + nex的最小值的时间复杂度是0(n),所以总的时间复杂度是 O(n logn)。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+9;
#define x first
#define y second
typedef long long ll;
pair<int,int>p[N];
ll pre[N],nex[N];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++)cin>>p[i].y>>p[i].x;sort(p+1,p+1+n);ll s=0;for(int i=1;i<=n;i++){pre[i]=pre[i-1];pre[i]+=s*(p[i].x-p[i-1].x);s+=p[i].y;}s=0;for(int i=n;i>=1;i--){nex[i]=nex[i+1];nex[i]+=s*(p[i+1].x-p[i].x);s+=p[i].y;}ll ans=1e18;for(int i=1;i<=n;i++){ans=min(ans,pre[i]+nex[i]);}cout<<ans<<endl;return 0;
}

当输入为:

3
2 3
3 1
1 5

输出为:

8

过程解释:

当我们在计算 pre 数组的时候:

  • 对于 i = 1:

    • 之前没有石头,所以 pre[1] = 0
    • 总重量更新为 s = 3(因为第一堆石头重量为3)。
  • 对于 i = 2:

    • 我们需要把第一堆石头从位置1搬运到位置3,花费为 3 * (3 - 1) = 6
    • pre[2] 就变成之前的 pre[1] 加上新花费,也就是 0 + 6 = 6
    • 总重量 s 现在变成 3 + 2 因为另外一堆石头重2,所以 s = 5
  • 对于 i = 3:

    • 现在我们把之前所有石头(总重量 s = 5)从位置3搬运到位置5,花费为 5 * (5 - 3) = 10
    • pre[3] 就是之前的 pre[2] 加上这个新花费,也就是 6 + 10 = 16
    • 最后更新总重量 s,加上最后一堆石头重1,所以 s = 6

pre数组的值反映的是把所有石头搬到当前位置得到的累计成本。

然后,我们需要再计算 nex 数组,它储存的是从最右侧开始往左搬运到当前位置的累计成本。最后,程序遍历所有石头位置,对于每一个位置计算 pre[i] + nex[i],也就是把所有石头搬到当前位置的总成本(往左和往右的成本之和)。最小的一个总成本就是我们要求的答案。

注:这样写也是可以的

for (int i = 1; i <= n; ++i) 
{pre[i] = pre[i - 1] + s * (q[i].x - q[i - 1].x); // 合并了继承和添加搬运成本的步骤s += q[i].y; // 更新到当前位置为止的总石头重量
}

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

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

相关文章

“抖动“ 与工作集

目录 "抖动" 的产生原因 "抖动" 产生的详细原因 "抖动" 的示例场景 解决"抖动" 的方法 缺页率与物理块数的关系 1. 缺页率与内存大小的关系 2. 虚拟内存技术 3. 缺页率与物理块数关系的分析 4. 示例图解 5. 管理策略 工作集…

Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路

技术背景 Android平台推流模块&#xff0c;添加文字或png水印&#xff0c;不是一件稀奇的事儿&#xff0c;常规的做法也非常多&#xff0c;本文&#xff0c;我们主要是以大牛直播SDK水印迭代&#xff0c;谈谈音视频行业的精进和工匠精神。 第一代&#xff1a;不可动态改变的文…

计算机网络9——无线网络和移动网络2无线个人区域网 WPAN

文章目录 一、蓝牙系统二、低速 WPAN三、高速 WPAN 无线个人区域网WPAN(Wireless Personal Area Network)就是在个人工作的地方把属于个人使用的电子设备(如便携式电脑、平板电脑、便携式打印机以及蜂窝电话等)用无线技术连接起来自组网络&#xff0c;不需要使用接入点AP&#…

【设计模式】创建型设计模式之 建造者模式

文章目录 一、介绍定义UML 类图 二、用法1 简化复杂对象具体构建过程省略抽象的 Builder 类省略 Director 类 三、用法2 控制对象构造方法、限制参数关系Guava 中使用建造者模式构建 cache 来进行参数校验 一、介绍 定义 建造者模式&#xff0c;将一个复杂的对象的构建过程与…

实用软件分享---简单菜谱 0.3版本 几千种美食(安卓)

专栏介绍:本专栏主要分享一些实用的软件(Po Jie版); 声明1:软件不保证时效性;只能保证在写本文时,该软件是可用的;不保证后续时间该软件能一直正常运行;不保证没有bug;如果软件不可用了,我知道后会第一时间在题目上注明(已失效)。介意者请勿订阅。 声明2:本专栏的…

MC联机无法连接到服务器怎么解决

MC联机无法连接到服务器&#xff1f;弹性云服务器来帮您解决&#xff01;在《我的世界》&#xff08;Minecraft&#xff0c;简称MC&#xff09;的联机冒险中&#xff0c;无法连接到服务器无疑是每个玩家最头疼的问题之一。无论是与好友组队探险&#xff0c;还是加入心仪的社区服…

Nginx-反向代理如何配置

反向代理 为服务响应方提供中转 正向代理 为服务请求方提供中转 后端的域名和ip要和反向代理的保持一致 加权轮询(weight1;)和ip_hash是不能一起用的 /usr/local/nginx/sbin/nginx -v //查看版本 反向代理 谁第一响应就解析谁 nginx-2的ip:192.168.241.10 安装nginx 启动…

Hive日志介绍

日志描述 日志路径&#xff1a;Hive相关日志的默认存储路径为“/var/log/Bigdata/hive/角色名”&#xff0c;Hive1相关日志的默认存储路径为“/var/log/Bigdata/hive1/角色名”&#xff0c;以此类推。 HiveServer&#xff1a;“/var/log/Bigdata/hive/hiveserver”&#xff0…

住宿管理系统 java+jsp+web三件套

文章目录 1、简要介绍2、数据库设计3、中间遇到的困难一、数据问题二、文件问题 4、项目 写了将近3周&#xff0c;人都写麻了 记录下&#xff0c;第一个 ss 代码 仅仅使用了layui作为前端UI框架&#xff0c;因为另一个项目用的也是他&#xff0c;感觉一些组件比较好用 后端是j…

从零开始学C语言系列之番外篇《初学单片机的路》

写在前面的话 入嵌入式&#xff0c;避免不了学C语言&#xff0c;那初学者知道要学&#xff0c;但大多都不知到要学到哪&#xff0c;基本都是推荐C语言学完结构体&#xff0c;指针足以&#xff0c;那前面需要学啥也没讲&#xff0c;要学多深也没讲&#xff0c;基本都是一头雾水。…

reverse入门刷题(6.9)

总结&#xff1a; 拿到附件&#xff0c;先运行看看有没有信息&#xff0c;再查壳&#xff0c;再IDA运行 1.Easy_vb 收获&#xff1a; 使用搜索&#xff1a;在String的时候用的是ctrlf 在IDA_view的时候使用搜索是Aitt 打开IDA&#xff0c;Aitt搜索MCTF&#xff08;关键字即…

文献阅读:Solving olympiad geometry without human demonstrations

文献阅读&#xff1a;Solving olympiad geometry without human demonstrations 1. 文章简介2. 方法介绍 1. Overview2. Symbolic deduce3. Language Model4. 联合使用 3. 实验考察 & 结论 1. 基础实验考察2. 结果分析3. 样例展示 4. 总结 & 思考 文献链接&#xff1a…

看似不同的事情,却是相同的坑

目录 一、背景二、过程1.遭遇战-微盘股的下杀2.不失为一件好事3.一切向后看吧&#xff0c;最近的学习感受4.该有的心境 三、总结 一、背景 也在一点点改变&#xff0c;期间势必要经历流血的过程&#xff1b;所谓无疯狂不成长&#xff0c;积极的心态去应对&#xff0c;去总结总…

引入Springcloud--Sleuth-链路追踪中MDC是如何获取到traceid和何时放入traceid的

在分布式项目中需要引入 spring-cloud-starter-sleuth框架来记录跟踪请求在不同服务之前流转的路径。在整个流转路径通过traceid将所有的路径给串联起来。 项目中需要保存traceid来实现日志快速搜索和定位&#xff0c;可以通过MDC.get("traceId")获取到traceId。 …

评书下载到u盘,下载到内存卡,下载到手机或电脑的方法

评书下载的方法有很多种&#xff0c;无论是通过什么方法&#xff0c;我们都可以快速的获取喜爱的评书。下面将详细介绍常见的评书下载方法&#xff0c;帮助您快速上手。 1、搜索“十方评书网”。 2、要下载那个评书家的选择那个评书家就可以。 3、点击进去后可以一键下载单部评…

nodejs 第三方库 exiftool-vendored

exiftool-vendored 是一款可以帮助你快捷修改图片信息的第三方库。如果你想要批量修改图片信息的话&#xff0c;那么它是一个不错的选择。 1.导入第三方库 在控制台中执行下面代码即可。 npm install exiftool-vendored --save2.获取信息 这里给出例子。 const { exiftool …

Elasticsearch中各种query的适用场景

Elasticsearch 提供了丰富的 Query 类型&#xff0c;以满足各种搜索需求。以下列举一些常见的 Query 类型&#xff0c;并分析其区别和应用场景&#xff1a; 一、 几个常用的基本Query 1. Term Query 应用场景: 查找包含特定词语的文档&#xff0c;适合精确匹配单个词语的场景…

【SpringBoot + Vue 尚庭公寓实战】标签和配套管理接口实现接口实现(六)

【SpringBoot Vue 尚庭公寓实战】标签和配套管理接口实现接口实现&#xff08;六&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】标签和配套管理接口实现接口实现&#xff08;六&#xff09;1、保存或更新标签信息2、根据id删除标签信息3、根据类型查询配套列表4、新…

Aptos Builder Jam 亚洲首站|见证 Aptos 公链 2024 年新突破

4 月下旬的「TinTin DESTINATION MOON」杭州站活动让我们构建下一个 Web3 巅峰的项目生态行动与未来战略。时隔三个月&#xff0c;「TinTin DESTINATION MOON」Aptos 线下活动将再次来到杭州&#xff0c;为 Aptos Builder Jam 亚洲首站火热造势&#xff0c;7 月 6 日诚邀 Web3 …

高精度|大数加减乘

一、大数加法 1.反转法 &#xff08;不开动态数组存&#xff09; #include<bits/stdc.h> using namespace std; string add(string s1,string s2){if(s1.length() < s2.length() ) swap(s1,s2);reverse(s1.begin(),s1.end());reverse(s2.begin(),s2.end());int carr…