Time Limit: 500MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
Description
To fulfill an assignment, a reconnaissance group of n people must cross the enemy‘s minefield. Since the group has only one mine detector, the following course of action is taken: two agents
cross the field to the enemy‘s side and then one agent brings the mine detector back to the remaining group. This is repeated until only two agents remain. These two agents then cross the field together.
Each person gets across the field at their own speed. The speed of a pair is determined by the speed of its slower member.
Find the minimal time the whole group needs to get over the minefield.
Input
The first line contains the integer n (2 ≤ n ≤ 100). The i-th of the following n lines specifies the
time the i-th member of the group needs to get over the minefield (the time is an integer from 1 to 600).
Output
Output the minimal total time the group needs to cross the minefield.
Sample Input
input | output |
---|---|
4 1 10 5 2 |
17 |
题目讲n个士兵过雷区,可就一个探测器,每次最多两个人一起走,还要有一个人把探测器拿回了,一直到全部人渡过雷区。一起走时即较慢的那个人的用时,求所用最短的时间
先讲下例子的走法,1和2过去(2),2回来(2+2),5和10过去(2+2+10),1回来(2+2+10+1),1和2再回去(2+2+10+1+2)。脑子笨这个例子就想了好久。
先排序,然后可能得最优解法有两种:
1.最小两个过去,最小的一个把探测器带回来,再带最大的过去,再带第二大的过去……
2.最小的两个过去,最小的回来,最大两个过去,第二小的回来……
要注意下结束条件,然后就交给递归吧。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<map> #include<cmath> #include<utility> #include<vector> using namespace std; #define eps 1e-6 #define inf 0x3f3f3f3f int a[1010]; int count(int n) { if(n==2) { return a[1]; } if(n==3) { return a[0]+a[1]+a[2]; } if(2*a[0]+a[n-1]+a[n-2]<a[0]+a[1]+a[n-1]+a[1]) { return 2*a[0]+a[n-1]+a[n-2]+count(n-2); } else { return a[0]+a[1]+a[n-1]+a[1]+count(n-2); } } int main() { int n; while(cin>>n) { for(int i=0;i<n;i++) { scanf("%d",a+i); } sort(a,a+n); cout<<count(n)<<endl; } return 0; }