1 条题解
-
0
解题思路:
本题要求在最短时间内让所有人过桥,每次最多两人且需携带手电筒。策略核心在于通过贪心算法选择最优的过桥顺序,以最小化总耗时。
关键步骤:
排序处理:将所有人的过桥时间从小到大排序,便于后续策略选择。
贪心策略选择:每次处理剩余最慢的两人,比较两种策略:
策略1:最快者带最慢两人过桥。总时间为 。
策略2:次快者配合最快者,总时间为 。
选择耗时更小的策略。
处理剩余人数:
剩余人时,总时间为 。
剩余人时,时间为较慢者的时间。C++实现:
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; int s[1050]; // 存储每个人过桥时间的数组 int main() { int a; scanf("%d",&a); // 读取人数 for(int i=0;i<a;i++) scanf("%d",&s[i]); // 读取每个人的过桥时间 if(a==1) { // 当只有一人时,直接往返两次(虽然实际不需要返回) printf("%d\n%d\n",s[0],s[0]); return 0; } sort(s,s+a); // 按过桥时间从小到大排序 int ans=a,sum=0; // 计算总耗时的主循环,处理剩余人数大于3的情况 while(ans>3) { // 两种策略的选择:最快带两慢 vs 次快带一慢 int sum1=2*s[0]+s[ans-2]+s[ans-1]; // 策略1:最快者来回带两最慢 int sum2=2*s[1]+s[0]+s[ans-1]; // 策略2:次快者和最快者配合 if(sum1>sum2) sum+=sum2; // 选择较小耗时的策略 else sum+=sum1; ans-=2; // 每次处理完两人,剩余人数减2 } // 处理剩余人数小于等于3的情况 if(ans==3) sum+=s[0]+s[1]+s[2]; // 三人一起过桥的总时间 else sum+=s[1]; // 只剩两人时,取较慢的那个的时间 printf("%d\n",sum); // 输出总耗时 // 以下部分负责输出具体过桥步骤 while(a>3) { // 根据两种策略的耗时选择输出方案 if(s[0]+s[a-2] < 2*s[1]) // 策略1更优 printf("%d %d\n%d\n%d %d\n%d\n",s[0],s[a-1],s[0],s[0],s[a-2],s[0]); else // 策略2更优 printf("%d %d\n%d\n%d %d\n%d\n",s[0],s[1],s[0],s[a-2],s[a-1],s[1]); a-=2; // 处理完两人后更新剩余人数 } // 处理剩余3人或2人的情况 if(a==3) printf("%d %d\n%d\n%d %d\n",s[0],s[2],s[0],s[0],s[1]); // 三人过桥的具体步骤 else printf("%d %d\n",s[0],s[1]); // 两人直接过桥 return 0; }
- 1
信息
- ID
- 1574
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 1
- 上传者