ny-47-过河问题

过河问题

时间限制: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

来源

POJ

解题思路:

两种方法:

方法一: 由用时最短的那个人啊a[0],依次和另一个人过河,然后返回。每次的时间是  2*a]+a[i]+a[i-1]。(时间节省在返回的人身上)。

方法二:

由前两个先过去,然后1返回,a[i]和[i-1]过去。a[1]返回。重复。每次过河的时间是a[0]+a[i]+2*a[1](时间节省在过河的人身上,相应返回时间增加了).

比较两次的时间最短的就是过河最短的时间。

程序代码:

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

int a[1100],time0,n,time1,time2;

int cmp(const void *a,const void *b)

{

    return *(int *)a - *(int *)b;

}

int min(int a,int b)

{

    if(a>b)

    return b;

    else

    return a;

}

void f()

{

    int i;

    if(n&1)

    {

      for(i=4;i<n;i+=2)

     {

         time1=2*a[0]+a[i]+a[i-1];            //分两种情况计算

         time2=a[0]+a[i]+2*a[1];

         time0+=min(time1,time2);

      }

    time0+=a[0]+a[2];

   }

   else

   {

        for(i=3;i<n;i+=2)

       {

        time1=2*a[0]+a[i]+a[i-1];

        time2=a[0]+a[i]+2*a[1];

        time0+=min(time1,time2);

        }

    }

}

int main()

{

    int T,i,sum;

    scanf("%d",&T);

    while(T--)

    {

        memset(a,0,sizeof(a));

        scanf("%d",&n);

        for(i=0;i<n;i++)

        {

            scanf("%d",&a[i]);

        }

        qsort(a,n,sizeof(a[0]),cmp);     //  按时间大小由小到大排序

        sum=0;

        time0=a[1];

        if(n==3)

        {

            time0+=a[0]+a[2];

        }

        else

        f();

        printf("%d ",time0);

    }

    return 0;

}

原文地址:https://www.cnblogs.com/zhouhongweihpu/p/3260888.html