Crossing River
Crossing River
题解:贪心
经典过河问题:先对过河的人速度降序排序,我们要知道想要使时间最短,有两个地方可以贪心
1.去的时候减少时间浪费,就是说让两个速度慢的人一起过河
2.回来的时候减少时间浪费,就是说让速度最快的回来
然后我们直接模拟分析
当n==1时,直接过河 ans += a[1];
当n==2时,直接过河 ans += a[2];
当n==3时,让最快的人来回送,ans+=a[1]+[2]+a[3];
当n==4时,我们比较一下先让速度最快的人送两个最慢的过河然后自己再回来接最后一个人,还是先让最快的把第二快的送过去,然后让最慢的两个人先过河,再让第二快的人把船开回来接第一个人即比较2*a[1]+a[4]+[3]+a[2]和3*a[2]+a[4]+a[1]
我们化简式子得:2*a[2] ? a[1]+a[3]
当n==5时,我们发现还是要先比较送两个人过去的情况,从而n-2=3,又变成了我们求过的问题,所以以此类推,我们每次都考虑只过两个人的情况;
#include <iostream>
#include <string>
#include <cstring>
#define Zeoy std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0)
#define all(x) (x).begin(), (x).end()
#define endl '\n'
using namespace std;
int a[1010];
int main(void)
{
Zeoy;
int t = 1;
cin >> t;
while (t--)
{
int n;
cin >> n;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
}
sort(a + 1, a + 1 + n);
int ans = 0;
while (n >= 4)
{
ans += min(a[n] + a[n - 1] + 2 * a[1], a[1] + 2 * a[2] + a[n]);
n -= 2;
}
if (n == 3)
{
ans += a[1] + a[2] + a[3];
}
else if (n == 2)
{
ans += a[2];
}
else if (n == 1)
ans += a[1];
cout << ans << endl;
}
return 0;
}