当前位置: 代码迷 >> 综合 >> Crossing River(贪心)
  详细解决方案

Crossing River(贪心)

热度:85   发布时间:2024-01-28 04:47:44.0

题面:多个人过河,但只有一艘船,每次最多只能在两个人,问全部人都过河的对短时间

首先来看下样例:四人渡河时间1 2 5 10,对短时间:17;样例中的渡河方式是①A+B(2),A(A,B任一返回结果不变)返回(1),②C+D(10),B返回(2),③A+C(2),渡河完成,用时为2+1+10+2+2=17,同时我们很容易能够想出另一种快速渡河的方式,即每次都是A和其他的人渡河,每次A返回,第一种优势方案用时为T(A)+3T(B)+T(D),第二种优势方案用时为2T(A)+t(B)+T?+T(D)

初始总人数不足四人时,比较简单,就不再赘述了。

当剩下的人总数大于四时,可以一直选择上述两种方式中的一种进行渡河,A代表渡河时间最短的人,B代表渡河时间第二小的人,C代表渡河时间第二大的人,D表示渡河时间最大的人,而且A,B虽一直在渡河,但每次行动后A,B仍然没有过河,所以两种优势方案总用时需要进行改变,第一种优势方案总用时为T(A)+2T(B)+T(D),第二种优势方案总用时为2T(A)+T?+T(D),当T(A)+2T(B)+T(D)<2T(A)+T?+T(D),化简为2*T(B)<T(A)+T?时采用优势方案一,否则采用优势方案二,最后只剩下三人时,总用时为Tsum+T(A)+T(B)+T?,剩下两人时总用时为Tsum+T(B)

AC代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>using namespace std;int arr[1010];int main() {int t;scanf("%d", &t);while (t--) {int n;scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &arr[i]);}sort(arr + 1, arr + 1 + n);int ans = 0;if (n < 4) {if (n == 1 || n == 2) ans = arr[n];else ans = arr[1] + arr[2] + arr[3];printf("%d\n", ans);continue;}while (n >= 4) {if (2*arr[2]<arr[1]+arr[n-1]) {ans += arr[1] + 2 * arr[2] + arr[n];}else {ans += 2 * arr[1] + arr[n] + arr[n - 1];}n -= 2;}if (n == 3) {ans += arr[3] + arr[1];}ans += arr[2];printf("%d\n", ans);}}