贪心算法:小船过河问题
题意:N我的过河,船每次只能坐两我的,船载每一个人过河的所需时间不一样t[i],每次过河的时间为船上的人的较慢的那个,问最快的过河时间。(船划过去要有一我的划回来)
最优选择:
先将全部人过河所需的时间按照升序排序考虑把单独过河所须要时间最多的两个旅行者送到对岸去,有两种方式:
1.最快的和次快的过河,而后最快的将船划回来;次慢的和最慢的过河,而后次快的将船划回来,时间:t[0]+2t[1]+t[n-1];
2.最快的和最慢的过河,而后最快的将船划回来,最快的和次慢的过河,而后最快的将船划回来,时间:2t[0]+t[n-2]+t[n-1]。ios
上述分析存在于至少四我的的时候,少于三我的状况,咱们单独讨论一下就好。算法
#include <stdio.h> #include <iostream> #include <cstdlib> #include <cmath> #include <cctype> #include <string> #include <cstring> #include <algorithm> #include <stack> #include <queue> #include <set> #include <map> #include <ctime> #include <vector> #include <fstream> #include <list> #include <iomanip> #include <numeric> using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf = 0x3f3f3f3f; const int N=1e3+5; int t[N]; int main() { int T,n; cin>>T; while(T--){ cin>>n; for(int i=0;i<n;i++){ cin>>t[i]; } sort(t,t+n);//排序 int sum=0,ks1,ks2; while(n>3){//条件选取 ks1=t[0]+2*t[1]+t[n-1]; ks2=t[n-1]+2*t[0]+t[n-2];//状况列举 if(ks1>ks2){ sum+=ks2; }else{ sum+=ks1; } n-=2; } if(n==3){//边界讨论 sum+=(t[0]+t[1]+t[2]); }else if(n==2){ sum+=t[1]; }else{ sum+=t[0]; } cout<<sum<<endl return 0; }