• 关于过河问题的感悟


    今天在群里面看到有人在讨论关于过河的最优解的问题。开始由于理解的错误,我做得完全错误,后面百度后,此问题的具体描述如下:

    有N个人想要用一条每次只能坐两人的船过河,因此,需要合理的安排来、回以使所有的人都能顺利过河。每个人过河的速度不同,两个人速度取决于速度较慢的一个。你的任务就是想一个策略让所有的人在最短的时间内均过河。

    要求 :时间限制:1000MS 内存限制:10000KB
    通过次数(Accepted):3 提交次数(Submit):24


    说明:
    输入
    第一行是一个表示测试用例次数的整数T(1<=T<=20),接下来是T个测试用例。每个测试用例的第一行是一个整数N,第二行包含N个整数代表每个人过河的时间。不会超过1000个人(即N<=1000)并且每个人的过河时间不会超过100秒。


    输出
    每一个测试用例,输出N个人过河所用的最短总时间。


    输入示例
    1
    4
    1 5 2 10

    输出示例
    17


    //算法

    1.正确的算法:
    如果n=3, 过河时间为A+B+C
    如果n<=2, 好算, 不费口舌了

    如果n>=4, 这个是重点:
    每次优先考虑把最慢两人送过河
    把n人中最快两人记为A,B, 最慢两人记为C,D(过河时间A<B<C<D), n人问题实质上转换为4人过河问题, 参考到4人过河时的优化,
    记AB过河, A回, CD过河, B回, 为方法X, 实质是利用最快两人进行优化, 耗时A+2B+D
    记AD过河, A回, AC过河, A回, 为方法y, 实质是利用最快一人来过河, 耗时2A+C+D
    每次比较这两个方法, 如果x快, 使用x方法, 如果y快, 则用y, 并且, 一旦某次使用y方法后, 以后都不用比较了, 全部使用y方法过河

    2.算法正确性证明:
    为什么每次先让最慢两人过河? 因为他们迟早要过河...早过晚过一样, 而晚过的话, 有可能时间不能被优化, 所以选择最先过
    为什么是两人, 不是三人? 因为这船一次只能两人, 三人问题和两人问题的优化一样, 所以一次考虑三人毫无意义, 同理, 三人以上不加考虑

    为什么某次用y过河后不用再比较xy了?
    先看这个例子:

    1 99 100 101
    用x方法是99+1+101+99= 300
    y方法是 101+1+100+1 = 203

    y比x快的原因是2A+C+D < A+2B+D, 即 A+C<2B
    容易想到, 从此以后A+C都会小于2B了(因为C越来越小)

    3.code

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[1001];
    int main()
    {
    int t,i,n,fast1,fast2,slow1,slow2,slow3,sum,l,r;
    cin>>t;
    while(t--)
    {
       sum=0;
       cin>>n;
       for(i=1;i<=n;i++)
        cin>>a[i];
       sort(a+1,a+n+1);
       fast1=a[1];fast2=a[2];slow1=a[n-1];slow2=a[n];slow3=0;
       l=1;r=n;
       while(n!=0)
       {
        if(n==1) {sum+=slow2;break;}
        if(n==2) {sum+=slow2;break;}
        if(n==3) {sum+=(slow2+slow1+fast1);break;}
        if(2*fast2>=fast1+slow1) {sum+=(slow1+slow2+2*fast1);r-=2;slow2=a[r];slow1=a[r-1];n-=2;}
        else {sum+=2*fast2+fast1+slow2;r-=2;slow2=a[r];slow1=a[r-1];n-=2;}
       }
       cout<<sum<<endl;
    }
    return 0;
    }

    摘自:http://hi.baidu.com/kk0602/blog/item/e9cadb1e1212fdf3e0fe0b03.html

    总结:

          1. 此问题描述的实际就是采用最好的去优化最差的,实现整体最优的平均化

         2. 此种思想首先让我想到的却是尊老爱幼,呵呵,因为活动能力最强的是青年。老年幼年都是需要呵护的对象。只有尊老爱幼才会实现社会的整体繁荣,也就是1中提到的平均最优

          3. 根据这种思想,其实也算是求带权图的最优便利方法,因此,按理来说,带权图也有最优遍历解法,这个我暂时不清楚,需要继续学习

        这样的话,上面问题的求解,其实就转换成了:一个无向有权图,找一条路径,使之遍历所有节点,要求权值之和最小。

         4. 听说在5人的时候,最优解是28秒,而不是29秒,这个,我无解。。,但是根据29秒算法

  • 相关阅读:
    学习OpenGL:笔记八
    学习OpenGL:笔记七
    学习OpenGL:笔记六
    学习OpenGL:笔记五
    学习OpenGL:笔记四
    将Redis加入到Windows服务中
    Oracle设置列宽,行数
    word文档最上面有一条不是页眉的线
    myeclipse中配置自己安装的Tomcat
    SSM框架mapper.xml模糊查询语句
  • 原文地址:https://www.cnblogs.com/foreverme/p/2581029.html
Copyright © 2020-2023  润新知