标签:过河 个人 int 题解 ans Crossing River 输入
题目描述
几个人过河,每次过两人一人回,速度由慢者决定,问过河所需最短时间。
输入格式
输入t组数据,每组数据第1行输入n,第2行输入n个数,表示每个人过河的时间。
输出格式
输出t行数据,每行1个数,表示每组过河最少时间。
输入样例
1
4
1 2 5 10
输出样例
17
题解
容易想到,我们要尽可能利用速度快的人,且尽可能先把慢的人送走。
据此可以想到贪心策略:设$n$个人的时间升序排列为$a_{1}$到$a_{n}$,那么我们就让第$n$个人把第$1$个人运到对岸,再让第$1$个人自己回来,然后$n = n - 1$,继续上述过程。
但是当我们运了第$(n - 1)$和第$n$个人时,时间为$a_{1} + a_{1} + a_{n - 1} + a_{n}$,此时还有一种策略,即先让第$2$个人运第$1$个人过去,第$1$个人回来,再让第$n$个人运第$(n-1)$个人过去,然后第$2$个人回来,这样总时间就为$a_{1} + a_{2} + a_{2} + a_{n}$。
当$a_{1} + a_{n - 1} > a_{2} + a_{2}$时,实际第二种方案好过第一种方案,每次去最优方案即可。
#include <iostream> #include <algorithm> #define MAX_N (100 + 5) using namespace std; int T; int n; int a[MAX_N]; int ans; int main() { cin >> T; while(T--) { ans = 0; cin >> n; for(register int i = 1; i <= n; ++i) { cin >> a[i]; } sort(a + 1, a + n + 1); while(n >= 4) { ans += min(a[1] + a[1] + a[n - 1] + a[n], a[1] + a[2] + a[2] + a[n]); n -= 2; } if(n <= 2) ans += a[n]; else ans += a[1] + a[2] + a[3]; cout << ans << "\n"; } return 0;参考程序
标签:过河,个人,int,题解,ans,Crossing,River,输入 来源: https://www.cnblogs.com/kcn999/p/10959338.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。