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

    题目描述 Description
        有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸。而东岸
    边有一条小船。 
        船太小了,一次只能乘坐两人。每个人都有一个渡河时间T,船划到对岸的时间等于船上渡河时间较
    长的人所用时间。 
    现在已知N个人的渡河时间T,Oliver想要你告诉他,他们最少要花费多少时间,才能使所有人都过河。 
        注意,只有船在东岸(西岸)的人才能坐上船划到对岸。

    输入输出格式 Input/output
    输入格式:
    输入文件第一行为人数N,以下有N行,每行一个数。 
    第i+1行的数为第i个人的渡河时间。
    输出格式:
    输出文件仅包含一个数,表示所有人都渡过河的最少渡河时间

    解析:这道题一开始没什么好的想法。但后来灵机一闪。
        首先我们要进行排序。
        我们用f[i]表示前i个人都过去的情况。很显然,对i的讨论是对i的过河方式的讨论。
        当i是一个人去西岸时,当然是由需时最少的1号把船开回来,把i带到西岸。f[i]=f[i-1]+t[1]+t[i]
        但这显然不一定是最优的。我们会发现,还可以让i和另一个慢的人一起过河,为了不让这两个人
    回来,我们当然要先让一个快的去西岸等着。再让一个人把船送回来。显然那两个慢性子就是i和i-1,
    把船送回来的当然是1。那1怎么回来呢?当然是2把船送回来,再把1带过去,于是就有:
        f[i]=f[i-2]+f[i]+f[1]+f[2]*2
        两种情况取最佳即可。
        边界:f[1]=t[1]; f[i]=t[2]
        时间复杂度为O(n),满足要求。

    代码如下: 

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    int t[100001],f[100001];
    int main()
    {
        int n;
        scanf("%d",&n);
        for (int i=1; i<=n; i++) scanf("%d",&t[i]);
        sort(t+1,t+1+n); //升序排列
        for (int i=1; i<=n; i++) f[i]=0;
        
        f[1]=t[1]; f[2]=t[2];
        for (int i=3; i<=n; i++) f[i]=min(f[i-1]+t[1]+t[i],f[i-2]+t[i]+t[1]+t[2]*2);
        printf("%d",f[n]);
        //system("pause");
        return 0;
    }  
    View Code

     

  • 相关阅读:
    python初级入门篇
    ADO.NET中DbConnection.GetSchema方法的使用总结
    连接Git@OSC操作步骤
    win7 免安装MariaDB
    Java Web入门学习(二) Eclipse的配置
    PowerDesigner16 生成的备注脚本,在sql server 2008 中报“对象名 'sysproperties' 无效”的错误的解决办法
    Java Web入门学习(一) STS与Tomcat配置
    ECharts-入门学习
    xampp使用技巧及问题汇总
    Spring boot注解
  • 原文地址:https://www.cnblogs.com/Shymuel/p/4393152.html
Copyright © 2011-2022 走看看