A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.
Input
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. Each case is preceded by a blank line. There won't be more than 1000 people and nobody takes more than 100 seconds to cross.
Output
For each test case, print a line containing the total number of seconds required for all the N people to cross the river.
Sample Input
1 4 1 2 5 10
Sample Output
17
一个非常巧妙的贪心问题,刚开始的时候以为只要保证让船回来的时候时间最短就好了,即让最小的那一个一直跟着船走,但并不是这样的。。
题解: 分两种过程,第一种就是上述过程,第二种情况是我们先让最快的跟次快的过河,然后让最快的回来,再让最慢的跟次慢的过河,再让次快的回来,这两种情况去较小的,前提是至少要有大于等于4个人,如果小于4个人的话,模拟就可以
还要注意奇数的情况 ,如果是奇数,那么最后会剩下3个人,即最快 次快 次次快,如果是偶数的话,由于我们每次减少两个,最后只剩下最快于次快
;
AC代码
#include<bits/stdc++.h> #include<iostream> #include<algorithm> using namespace std; const int N=1E5+7; int arr[N]; int main(){ int t; cin>>t; while(t--){ int n; cin>>n; for(int i=1;i<=n;i++) scanf("%d",&arr[i]); sort(arr+1,arr+1+n); int ans=0; if(n==1) ans=arr[1]; else if(n==2) ans=arr[2]; else if(n==3) { ans+=arr[3]+arr[1]+arr[2]; } else { int sum1,sum2; for(int i=n;i>=4;i-=2){ sum1=arr[i]+arr[i-1]+arr[1]+arr[1]; sum2=arr[2]+arr[1]+arr[i]+arr[2]; ans+=min(sum1,sum2); } if(n&1) ans+=arr[3]+arr[1]+arr[2]; else ans+=arr[2]; } cout<<ans<<endl; } return 0; }
这篇博文讲的贼好。
https://blog.csdn.net/Cworld2017/article/details/81503102