趣味程序设计_过桥问题

题目描述

过桥问题。有N(N≥2)个人在晚上需要从X地到达Y地,中间要过一座桥,过桥需要手电筒(而他们只有1个手电筒),每次最多两个人一起过桥(否则桥会垮)。N个人的过桥时间依次存入数组t[N]中,分别为:t[0], t[1], ……, t[N-1]。过桥的速度以慢的人为准!注意:手电筒不能丢过桥!问题是:编程求这N个人过桥所花的最短时间。

输入

有多组测试数据,

每组数据先输入一个人数N,然后输入这N个人过桥所花的时间。

输出

输出对应的最短时间。

样例输入

4 1 2 5 104 5 2 10 1

样例输出

17

17

思路:

4人过桥问题最佳方案构造法:以下是构造N个人(N≥1)过桥最佳方案的方法:
1)       如果N=1、2,所有人直接过桥。
2)       如果N=3,由最快的人往返一次把其他两人送过河(本次过去3个人)。
3)       如果N≥4,设ZKer、CKer为走得最快和次快的旅行者,过桥所需时间分别为Tzk、Tck;而ZMer、CMer为走得最慢和次慢的旅行者,过桥所需时间分别为Tzm、Tcm。那么
a)        当2*Tck>=Tzk+Tcm时,使用模式一将ZMer和CMer送过桥;(模式一:ZKer、ZMer过去,ZKer返回送手电,再ZKer、CMer过去,ZKer返回送手电,即总是由最快的把2个最慢的送过桥。本模式实际将2个最慢的人送过桥,用时Tzm+Tzk+Tcm+Tzk);
b)        当2*Tck<Tzk+Tcm时,使用模式二将ZMer和CMer送过桥;(模式二:ZKer、CKer过去,ZKer返回送手电,再ZMer、CMer过去,CKer返回送手电。本模式实际将2个最慢的人送过桥,用时Tck+Tzk+Tzm+Tck)。
这样就使问题转变为N-2个旅行者的情形,从而递归解决之。编写递归函数解决这个问题最简单。此算法思路来自于:
http://www.360doc.com/content/080706/02/37063_1402145.html
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int str[10005];
int main()
{
   int n,i;
   while(scanf("%d",&n)==1)
   {     int sum=0;
        for(int i=0;i<n;i++)
            scanf("%d",&str[i]);
 
         sort(str,str+n);
       while(n>=4)
        {
            if(2*str[0]+str[n-1]+str[n-2]>2*str[1]+str[0]+str[n-1])
                sum+=2*str[1]+str[0]+str[n-1];
            else
                sum+=2*str[0]+str[n-1]+str[n-2];
            n-=2;
        }
        if(n==3)
            sum+=str[0]+str[1]+str[2];
        else if(n==2)
            sum+=str[1];
        else
        sum+=str[0];
        printf("%d\n",sum);
 
   }
}


 

你可能感兴趣的:(逻辑推理)