NC207781 迁徙过程中的河流
题目
题目描述
牛市的幸存的先民在流星雨之后就忍痛离开了这片土地,选择迁徙,在迁徙的途中,他们需要渡过一条河。因为牛市的树木在流星雨中被严重破坏,所以他们只造出了一艘小船,船太小了,一次只能乘坐两人。
牛市的先民们每个人划船的速度都不尽相同,所以每个人都有一个渡河时间T,为了保证船的平衡,当穿上有两个人的时候,需要他们按照慢的那个人的速度划船,也就是说船到达对岸的时间等于船上渡河时间长的那个人的时间。
现在已知N个人的渡河时间T,请问最少要花费多少时间,才能使所有人都过河。
输入描述
输入文件第一行为先民的人数 ,以下有N行,每行一个整数为每个人的渡河时间。
输出描述
输出文件仅包含一个数,表示所有人都渡过河的最少渡河时间。
示例1
输入
4 5 7 11 16
输出
42
说明
首先1,2先到河对岸花费7,然后1回来花费5,3,4到河对岸花费16,2回来花费7,1,2再到河对岸花费7
题解
知识点:线性dp,贪心。
给出一个贪心结论,因为时间短的和时间长的一起无法发挥时间短的收益,因此要么用时间最短的人作为运输媒介来回跑(这因为最短的人作媒介一定使得来回运输一个人的成本最低),要么两个时长相近的人一起。显然,先从小到大排序,方便处理。
设 表示运到第 个人的最短时间。先让最短时间的两人过去作为运输媒介, 。第一种方法:先用 让 号回去,用 接 号过去,共 ;第二种方法:先用 让 回去,再用 让 和 过去,再用 让 回去,用 让 和 过去,共 。于是有转移方程:
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; int t[100007], dp[100007];///表示运了i个人 int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; for (int i = 1;i <= n;i++) cin >> t[i]; sort(t + 1, t + n + 1);///从小到大运人 dp[1] = t[1]; dp[2] = t[2]; for (int i = 3;i <= n;i++) dp[i] = min(dp[i - 1] + t[1] + t[i], dp[i - 2] + t[1] + t[i] + 2 * t[2]); ///先让最小的两人过去,用这两个人运。因为能坐两个人,所以可以考虑两种情况 ///1回来接i过去;1回来i-1和i过去,2回来接1回去 cout << dp[n] << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16574312.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效