【算法分析】
这道题其实属于动态规划,设dp[n]表示n个人过完河所需的时间。
可以先将数组排序,过河时间最短的人在前面,即a[1]. 过河有两种情况分析
倒着思考:当n个人过完河,船也跟着过来了。所以当n-1人过完河时,船也是跟着过来了。(花费时间最短时间dp[n-1])
1、当桥边只剩一个人时,可以让花费时间最少的那个人a[1]过来送船,人员n和人员1一同过河,花费时间为a[n]; 则dp[n]=dp[n-1]+a[n]+a[1];
2、当桥边剩两个人时,即n-2人已经过河(时间为dp[n-2]),这样人员1先去送船(时间a[1]),然后人员n和人员n-1同时过河,(时间为a[n]),然后人员2来送船(时间为a[2]),然后人员1和人员2过桥(时间为a[2]) dp[n]=dp[n-2]+a[1]+2*a[2]+a[n];
最短时间:dp[n]=min( dp[n-1]+a[n]+a[1] , dp[n-2]+a[1]+2*a[2]+a[n] );
【代码】
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1010;
int a[N],dp[N];
int main(){
int T;
int n;
cin>>T;
while(T--){
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
dp[0]=a[0];
dp[1] =a[1];
for(int i=2;i<n;i++)
dp[i] = min(dp[i-1]+a[0]+a[i],dp[i-2]+a[0]+a[i] + a[1]*2);
cout<<dp[n-1]<<endl;
}
return 0;
}