NYOJ-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

思路还是挺拐弯的。。。
先说说样例17是怎么来的
1和2过去1回来,time+=2+1
5和10过去2回来,time+=10+2
1和2一块过去。time+=2
time=17;

首先对时间sort升序排列
sort排序http://blog.csdn.net/qq_32680617/article/details/50629215

其次过河有两种情况
比较特殊也就是样例采用的过河方法
a[0]和a[1]过去 ,a[0]回来;a[1]留在对岸
a[n-1]和a[n-2]过去,a[1]回来;a[n-1],a[n-2]留在对岸
所用时间为a[1]+a[0]+a[n-1]+a[1]

另一种情况较为常规
a[0]和a[n-1]过去,a[0]回来,a[n-1]留在对岸
a[0]和a[n-2]过去,a[0]回来,a[n-2],a[n-1]留在对面
所用时间为a[n-1]+a[0]+a[n-2]+a[0]

当人数大于4时采取上述方法,一次过去两个人
当人数小于4时,自己拿笔算算吧。

代码

#include<stdio.h>
#include<string.h>
#include<stack>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        int a[1001]= {0};
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);//时间升序排列
        int sum=0;
        while(n>=4)
        {//a[n-1]代表用时最长,a[n-2]代表用时第二长
            if(a[n-1]+a[0]+a[n-2]+a[0]<a[1]+a[0]+a[n-1]+a[1])//两种过河方式时间比较
            {
                sum=sum+a[n-1];//a[0]和a[n-1]一起过去
                sum=sum+a[0];//a[0]回来
                sum=sum+a[n-2];//a[0]和a[n-2]一起过去
                sum=sum+a[0];//a[0]回来
            }
            else
            {
                sum=sum+a[1];//a[0]和a[1]一起过去
                sum=sum+a[0];//a[0]回来
                sum=sum+a[n-1];//a[0]和a[n-1]一起过去
                sum=sum+a[1];//a[1]回来
            }
            n=n-2;//一个循环处理两人次
        }
        if(n==1)//最后还剩几个人
            sum=sum+a[0];
        if(n==2)
            sum=sum+a[1];
        else if(n==3)
            sum=sum+a[0]+a[1]+a[2];
        printf("%d\n",sum);
    }
    return 0;
}

你可能感兴趣的:(贪心算法,Sort排序)