链接
http://poj.org/problem?id=1700
题意
n个人需要过河,有一条船,每次最多可以乘两人,每个人都有一个过河需要时间a,两个坐船过河需要的时间为速度慢的需要的时间,即时间为两个人需要时间最多的那个,问最少需要多少时间过河;
题解
这里考虑两种过河思路,首先需从小到大排个序,然后一次性考虑两个人,比如让a[n]和a[n-1]都过河,如下;第一种是让a[1]和a[n]一起过河(即所需时间最少的与最大的一起过河),然后让a[1]回来,然后a[1]与a[n-1]过河a[1]回来,所需时间为2a[1]+a[n]+a[n-1],第二种是,让a[1]与a[2]过河,然后a[1]回来,a[n]与a[n-1]过河,然后a[2]回来,所需时间为a[1]+2a[2]+a[n],即在这二者之间取较小者,最后让剩下所需过河人数减-2(即一次性考虑两个人);
代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
using namespace std;
#define inf 0x7f7f7f7f
#define maxn 51000
#define mod 1000000007
#define N 1
#define P 2
typedef long long ll;
int t,n,a[1004];
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+1+n);
int res=0;
if(n<=2) {
cout << a[n] << endl;
continue;
}else if(n==3){
cout<<a[1]+a[2]+a[3]<<endl;
continue;
}
for(int i=n;;i-=2){
if(i==3){
res+=(a[1]+a[2]+a[3]);
break;
}else if(i>4){
res+=min(2*a[2]+a[1]+a[i],2*a[1]+a[i]+a[i-1]);
}else if(i==4){
res+=min(3*a[2]+a[1]+a[i],a[2]+2*a[1]+a[i]+a[i-1]);
break;
}
}
cout<<res<<endl;
}
}