过河问题-贪心
题目是这样的:
时间限制: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
做这道题目的时候,真的很气,去年做过的题目,现在居然写不出来,我要发疯了,aaaaaaaaa
说一下:解题思想吧:
是傻子都会想到:回来送手电的人的时间尽量少,尽量少,所以就有一下两种最好的方案:
按过桥时间从小到大排序
一:每次都是最快的那个人(time[0])和末尾最慢的那个人(time[n])过去,然后最快那个回来,一直循环下去,直到全部过去,
time[n]+time[0];
二:最快的两个(time[0],time[1])过河,接着最快的回来,然后最慢的两个人过去,然后time[1]次快的人回来,一直循环.....
所以最短的时间应该是两个的最小值:min(time[n]+time[0]+time[n-1]+time[0],time[1]+time[0]+time[n]+time[1]);
代码实现如下:
import java.util.Arrays;
import java.util.Scanner;
public class Main
{
static final int MAX = 1005;
static int time[] = new int[MAX];
public static void main(String []args)
{
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
for(int i = 0 ; i < T ; i++)
{
int N = cin.nextInt();
for(int j = 0 ; j < N ; j++)
{
time[j] = cin.nextInt();
}
Arrays.sort(time,0,N);
if(N == 1)
{
System.out.print(time[0] + "\n");
}
else if(N == 2)
{
System.out.print(time[1] + "\n");
}
else if(N == 3)
{
System.out.print(time[0]+time[1]+time[2] + "\n");
}
else
{
printTime(N);
}
}
}
static void printTime(int N)
{
int sum = 0;
int k = time[1] + time[0];
int i;
for(i = N-1 ; i > 2 ; i = i - 2)
{
sum += Math.min(k+time[i]+time[1],time[i]+time[i-1]+2*time[0]);
}
if(i == 1)
{
sum += time[1];
}
else if(i == 2)
{
sum += k+time[2];
}
System.out.print(sum + "\n");
}
}