电梯问题(推公式)
题意描述
一幢 层的大楼有一部电梯停在第一层,它一次最多容纳 个人,而且只能在第 层至第
层中某一层停一次。
对于每个人来说,他往下走一层感到 分不满意,往上走一层楼梯感到 分不满意。
现在有 个人在第一层,并且他们分别住在第 层至第 层中的每一层,问:电梯停在哪一层时,可以使得这 个人不满意的总分达到最小?最小值为多少?
(有些人可以不乘电梯 即直接从第一层走上去)
输入格式
一个数 ,表示该大楼有 层
输出格式
一行两个整数,分别表示停在 第几层 以及最小的 不满意总分
(如果有若干层不满意总分相等,输出层数最低的一层)
输入样例:
33
输出样例:
27 316
数据范围
分析
考虑枚举在哪一层停下来,算出在当前层停电梯造成的不满意度,然后求个最小的不满意度即可。
前面一步很好想,问题是如何求在当前层停下来,所有人的总不满意度
我们假设当前枚举到了在第 层停电梯
1.对于住在第 层及以上的人:
他们的不满意程度很好求,直接走上去,代价为所有住在楼层 的人所在层数减去 乘上 的总和:
2.对于住在第 层以下楼层的人:
注意到题目说可以有不乘电梯直接从一楼走到家的方案,故我们需要考虑让哪些人不坐电梯才能使代价最小。
首先我们注意到不乘电梯的人与乘电梯的人会有一个明显的分界线,即存在一个特殊的楼层,该楼层即其上面的人通过做电梯再走下来的方案到家,该楼层下面的人直接从一楼走上来。
因为走上来的代价每层为 ,但走下来的代价只有,所以我们尽可能考虑多往下走,但也不是一定往下走都会最优比如我家只住 楼,但电梯在 层才会停,与其从 层走下来,不如直接从一楼就走上去。
令这个特殊的楼层为
对于 层以下的人来说,直接走上来是更好的选择,总代价为:
对于 层及以上的人来说,就坐电梯到 层再直接走下来即可,总代价为:
两部分相加即为:
我们将它展开得到一个关于 的二次函数:(由于后面与 无关的项与该式在何时取最小值无关,这里用省略号代替)
根据我们小学二年级所学的关于二次函数的有关知识,可知当 取 的时候,该式子最小
故 的取值就为
我们不能忽略了这个 不一定为整数,所以当我们要取这个整数 时, 应该是在 这个数上取整以及下取整中选出一个值,使得其带来的价值最小,分别求取 即可。
时间复杂度是
Code:
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL get(int m, int k) {
return (LL)(m - 1) * m * 3 / 2 + (LL)(k - m) * (k - m - 1) / 2;
}
int main() {
int n; cin >> n;
LL res = 1e18;
int pos = 2;
for (int k = 2; k <= n; k ++ ) {
LL sum = 0;
int down = (k + 1) / 4; // 下取整
int up = (k + 4) / 4; // 上取整
LL s1 = get(down, k), s2 = get(up, k);
sum += min(s1, s2);
sum += (LL)(n - k + 1) * (n - k) / 2 * 3;
if (sum < res) {
res = sum;
pos = k;
}
}
cout << res << ' ' << pos << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)