zoukankan      html  css  js  c++  java
  • ACM 过河问题

    过河问题

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:5
     
    描述

    在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。 

     
    输入
    第一行是一个整数T(1<=T<=20)表示测试数据的组数
    每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河
    每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100)
    输出
    输出所有人都过河需要用的最少时间
    样例输入
    1
    4
    1 2 5 10
    样例输出
    17

    此题是阿里的一道笔试题,主要用贪心算法求解
    分成两种情况(假设时间已经排序)

    (1)最小时间把次最大和最大的时间送过去,花费的时间为2s[0]+s[n-2]+s[n-1]
      如 1 7 8 9,则为1把9送过去,1回来,1再把8送过去,1在回来,则能把8,9送过去,时间为19
      像 1 2 4 5,则为1把5送过去,1回来,1再把4送过去,1在回来,则能把4,5送过去,时间为11
    (2)最小和次小把最大和次大一起送过去,话费时间为s[0]+2s[1]+s[n-1]
    如 1 7 8 9,则为1,7送过去,1回来,8,9送过去,7回来,则能把8,9送过去,时间为24
    像 1 2 4 5,则为1,2送过去,1回来,4,5送过去,2回来,则能把4,5送过去,时间为10
    故两种方法中选取最优的
    #include <iostream>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    int main(){
        int T;
        cin >> T;
        for(int icase = 0; icase < T; icase++){
            int n;
            cin >> n;
            vector<int> s(n);
            for(int i = 0 ;i < n; ++i) cin >> s[i];
            sort(s.begin(),s.end());
            vector<int> ss;
            int res = 0;
            if(n > 3){
                while(n>3){
                    res+=min(2*s[0]+s[n-2]+s[n-1],s[0]+2*s[1]+s[n-1]);
                    n-=2;
                }
            }
            if(n <= 2){
                res+=s[n-1];
            }else if(n == 3){
                res+=s[0]+s[1]+s[2];
            }
            cout<<res<<endl;
        }
    }
    
    
    



    
    


  • 相关阅读:
    刷题总结——疫情控制(NOIP2012提高组)
    刷题总结——竞赛得分(ssoj)
    刷题总结——货车运输
    刷题总结——火柴排队(NOIP2013)
    刷题总结——烽火传递(单调队列+dp)
    刷题总结——道路覆盖(ssoj)
    刷题总结——过河(NOIP2015)
    刷题总结——子串(NOIP2015提高组)
    linux shell 学习笔记--文件测试符
    linux shell 学习笔记--比较操作
  • 原文地址:https://www.cnblogs.com/xiongqiangcs/p/3637389.html
Copyright © 2011-2022 走看看