1. 问题分析与算法设计
1.1 问题重述与理解
这是一个经典的过桥问题变种。题目描述如下:一群旅行者需要在夜间过桥,他们只有一支火把。每次最多只能有两个人同时过桥,且必须携带火把。过桥时间以两人中较慢者的时间为准。我们需要计算所有旅行者全部过桥的最短总时间。
关键约束条件:
- 每次过桥人数:1-2人
- 必须携带火把
- 过桥时间取较慢者
- 初始所有人都在桥的同一侧
1.2 输入输出分析
输入格式:
- 第一行:旅行者人数n
- 接下来n行:每个旅行者的过桥时间(已排序)
输出格式:
- 一个整数:所有旅行者过桥的最短总时间
示例分析:
输入:
code复制4
6
7
10
15
最优解为42,对应的过桥顺序可能是:
- 6和7过桥(耗时7)
- 6带火把返回(耗时6)
- 10和15过桥(耗时15)
- 7带火把返回(耗时7)
- 6和7过桥(耗时7)
总时间:7+6+15+7+7=42
1.3 算法选择与思路
这个问题属于典型的贪心算法应用场景。我们需要考虑两种主要的过桥策略:
策略A(快带慢):
- 最快的两人先过桥(时间t2)
- 最快的人带火把返回(时间t1)
- 最慢的两人过桥(时间tn)
- 次快的人带火把返回(时间t2)
总时间:t2 + t1 + tn + t2
策略B(快带快):
- 最快和最慢的人过桥(时间tn)
- 最快的人带火把返回(时间t1)
- 最快和次慢的人过桥(时间tn-1)
- 最快的人带火把返回(时间t1)
总时间:tn + t1 + tn-1 + t1
在实际计算中,我们需要比较这两种策略的时间消耗,选择较小的那个。对于剩余人数≤3的情况,可以直接处理。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 代码实现详解
2.1 预处理与输入处理
cpp复制#include<bits/stdc++.h>
using namespace std;
long long n,a[1000005],sum; //数组开大点防止越界
int main()
{
scanf("%lld",&n); //使用scanf提高输入效率
for(int i = 1;i <= n;i++)
scanf("%lld",&a[i]);
sort(a
