csp信奥赛C++高频考点专项训练之贪心算法 --【跳跃与过河问题】:过河问题

csp信奥赛C++高频考点专项训练之贪心算法 --【跳跃与过河问题】:过河问题

题目描述

有一个大晴天,Oliver 与同学们一共 N N N 人出游,他们走到一条河的东岸边,想要过河到西岸。而东岸边有一条小船。

船太小了,一次只能乘坐两人。每个人都有一个渡河时间 T T T,船划到对岸的时间等于船上渡河时间较长的人所用时间。

现在已知 N N N 个人的渡河时间 T T T,Oliver 想要你告诉他,他们最少要花费多少时间,才能使所有人都过河。

注意,只有船在东岸(西岸)的人才能坐上船划到对岸。

输入格式

输入文件第一行为人数 N N N,以下有 N N N 行,每行一个数。

第 i + 1 i+1 i+1 行的数为第 i i i 个人的渡河时间。

输出格式

输出文件仅包含一个数,表示所有人都渡过河的最少渡河时间。

输入输出样例 1
输入 1
复制代码
4
6
7
10
15
输出 1
复制代码
42
说明/提示
数据范围

对于 40 % 40\% 40% 的数据满足 N ≤ 8 N\le8 N≤8。

对于 100 % 100\% 100% 的数据满足 4 ≤ N ≤ 10 5 , 1 ≤ T ≤ 10 7 4\le N\le10^5,1\le T\leq 10^7 4≤N≤105,1≤T≤107。

样例解释
  • 初始:东岸 { 1 , 2 , 3 , 4 } \{1,2,3,4\} {1,2,3,4},西岸 { } \{\} {};
  • 第一次:东岸 { 3 , 4 } \{3,4\} {3,4},西岸 { 1 , 2 } \{1,2\} {1,2},时间 7 7 7;
  • 第二次:东岸 { 1 , 3 , 4 } \{1,3,4\} {1,3,4},西岸 { 2 } \{2\} {2},时间 6 6 6;
  • 第三次:东岸 { 1 } \{1\} {1},西岸 { 2 , 3 , 4 } \{2,3,4\} {2,3,4},时间 15 15 15;
  • 第四次:东岸 { 1 , 2 } \{1,2\} {1,2},西岸 { 3 , 4 } \{3,4\} {3,4} 时间 7 7 7;
  • 第五次:东岸 { } \{\} {},西岸 { 1 , 2 , 3 , 4 } \{1,2,3,4\} {1,2,3,4} 时间 7 7 7。

所以总时间为 7 + 6 + 15 + 7 + 7 = 42 7+6+15+7+7=42 7+6+15+7+7=42,没有比这个更优的方案。

思路分析

这是一个经典的过河问题(Bridge and Torch Problem),目标是让所有人从东岸到西岸,船一次最多两人,耗时取较慢者,求最小总时间。

核心贪心策略 (当人数 ≥4 时):

每次将最慢的两人(c, d)送过河,有两种最优方案:

  1. 方案一 :最快两人(a, b)过河 → a 返回 → 最慢两人(c, d)过河 → b 返回
    耗时:a + 2*b + d
  2. 方案二 :最快一人(a)带最慢(d)过河 → a 返回 → a 带次慢(c)过河 → a 返回
    耗时:2*a + c + d

取较小值累加,然后去掉最慢两人,重复直到剩余人数 ≤ 3。

剩余人数处理(下标从1开始):

  • 1 人:t[1]
  • 2 人:t[2]
  • 3 人:t[1] + t[2] + t[3]

复杂度:排序 O(N log N),模拟 O(N),可通过 N=1e5。


代码实现

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int M=100010;//最大人数
int t[M];//存储过河时间

int main() {
    int n;
    cin>>n;//读入人数
    for(int i=1;i<=n;++i) cin>>t[i];//读入每个人的时间
    sort(t+1,t+n+1);//升序排序

    long long ans=0;//总时间
    while(n>3){//当人数大于3时,每次送走最慢两人
        int s1=t[2]+t[1]+t[n]+t[2];//方案1: a,b去; a回; c,d去; b回
        int s2=t[n]+t[1]+t[n-1]+t[1];//方案2: a,d去; a回; a,c去; a回
        ans+=min(s1,s2);//取较小值累加
        n-=2;//最慢两人已过河
    }
    //处理剩余≤3人
    if(n==1) ans+=t[1];//只剩1人
    else if(n==2) ans+=t[2];//剩2人
    else ans+=t[1]+t[2]+t[3];//剩3人

    cout<<ans<<endl;//输出结果
    return 0;
}

功能分析

  • 输入处理 :使用静态数组 t[M] 存储时间,下标从1开始,先读取人数 N,再读取 N 个时间值存入 t[1]t[N]
  • 排序 :对 t[1]t[N] 升序排序,使 t[1] 为最快,t[N] 为最慢。
  • 贪心模拟 :当 N>3 时,循环计算两种经典方案的耗时(方案1:t[2]+t[1]+t[N]+t[2],方案2:t[N]+t[1]+t[N-1]+t[1]),选择较小的累加到答案中,然后 N 减少 2(去掉最慢两人)。
  • 边界处理:剩余 1、2 或 3 人时,直接按最优方式计算时间并累加。
  • 输出 :打印最小总时间(使用 long long 防止溢出)。

各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
是个西兰花1 小时前
C++11:智能指针
开发语言·c++·智能指针·rall
CN-Dust1 小时前
【C++专题】输出cout例题
开发语言·c++
沉默-_-2 小时前
备战蓝桥杯-哈希
c++·学习·算法·蓝桥杯·哈希算法
Reese_Cool2 小时前
【STL】蓝桥杯/天梯赛终极杀器!10个C++字符串核心技巧,暴力破解高频考点
开发语言·c++·蓝桥杯·stl
拼好饭和她皆失2 小时前
基础算法--写给算法小白的模板指南:快速掌握核心代码,蓝桥杯必备模板
算法
吞下星星的少年·-·2 小时前
rotate函数应用模板
算法
AI科技星2 小时前
人类首张【全域数学公理体系】黑洞内部结构图—基于「0-1-∞」三元本源的全维深度解析
人工智能·算法·机器学习·数学建模·数据挖掘·量子计算
paeamecium2 小时前
【PAT甲级真题】- Recover the Smallest Number (30)
数据结构·算法·pat考试·pat
hehelm2 小时前
C++ 模拟实现 AVL 树
开发语言·c++