【题目】
有1个人,要把n匹马从A村运往B村。
初始时,人和马都在A村。每次骑1匹马牵1匹马,回来时骑1匹马。
已知每匹马从A村到B村需要的时间(数字越大越慢)
两匹马同行时只能迁就较慢者。
求所有马匹都运到B村的最小的运输时间(此时,人和马都在B村)。
程序首先输入一个整数n(n<100),表示有n匹马。
接着是n行整数,表示马从A村到B村的所用的分钟数(小于1000)
程序输出:1个整数,表示所有马匹均运到B村的最小总耗时。
例如,
输入:
3
1
2
4
程序应输出:
7
输入:
4
1
4
2
5
程序应该输出:
12
【分析】
在运送马匹的过程中,会发现有两种情况:1.用最快的马运;2.用最快的马和次快的马运。
比如:
1 4 2 5 这种情况,如果用最快马运4 5 两匹马需时4+1+5+1=11;如果用最快马和次快马运,先1 2过去,然后2回来,4 5一起过去,1回来,需时2+2+5+1=10
1 3 4 5 这种情况,如果用最快马运4 5两匹马需时4+1+5+1=11;如果用最快马和次快马运,先1 3过去,然后3回来,4 5一起过去,1回来,需时3+3+5+1=12
通过以上的例子我们可以总结出,有时候单匹马运输快,有时候两匹马运输快,所以在程序中需要判断一下到底哪种需时少一些,就采用哪种方案。
【源码】
public class Test006 {
private static int sum = 0;
private static int[] a;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
sc.close();
// 对马匹运输时间进行从小到大的排序
Arrays.sort(a);
transferHorses(n);
System.out.println(sum);
}
// 在运输的过程中,变化的东西是什么,A村还有多少个马匹待运,一直在减少
// 把A村待运的马的数量抽象为变量x,x一直在减少
private static void transferHorses(int x) {
if (x == 0) {
// 如果A村还没有马了,递归结束
return;
}
if (x == 1) {
// 如果A村还有一匹马,一定是最快的马,一次运输
sum += a[0];
return;
}
if (x == 2) {
// 如果A村还有两匹马,一定是最快的马和次快的马,一次运输
sum += a[1];
return;
}
if (x == 3) {
// 如果A村还有三匹马,是最快的三匹马,两次运输
sum += a[0] + a[1] + a[2];
return;
}
// 如果用最快马和次快马运输最后面两匹马,需要花的时间是time1
int time1 = a[0] + 2 * a[1] + a[x - 1];
// 如果只用最快马运输最后面两匹马,需要花的时间是time2
int time2 = 2 * a[0] + a[x - 2] + a[x - 1];
// 将运输两匹马的消耗时间加上
if (time1 < time2) {
sum += time1;
} else {
sum += time2;
}
// 继续递归运输马匹
transferHorses(x - 2);
}
}