当前位置: 代码迷 >> 综合 >> POJ - 1700 crossing river(贪心算法)
  详细解决方案

POJ - 1700 crossing river(贪心算法)

热度:4   发布时间:2023-11-25 09:35:45.0

crossing river

几个人过河,每次过两人一人回,速度由慢者决定,问过河所需最短时间。

【输入】
输入t组数据,每组数据第1行输入n,第2行输入n个数,表示每个人过河的时间。

【输出】
输出t行数据,每行1个数,表示每组过河最少时间。

【输入样例】
1
4
1 2 5 10
【输出样例】
17
题意:多人过河,没人速度都不同,小船一次最多载两个人,速度取两人中较慢的一个。
首行给出T,代表有T组数据,每组数据第一行给出N,代表接着一行有N个人的过河时间,输出最小过河时间。

思路:两种过河方案
一:最快次快去,最快回,最慢次慢去,次快回,最慢次慢过河了。
二:最快最慢去,最快回,最快次慢去,最快回,最慢次慢过河了。
每轮可以送过去两个人,每次取耗时较少的方案,直至剩余人数小于4,再特判剩下的几个人即可。

我最开始认为是最快的和最慢的一起过河,最快的回来,可是并不得17,
后来发现其实是
1和2过河,1回来 用时2+1
4和5过河,2回来 用时5+2
最后1和2过河,用时1+2,总用时17
所以我们计算时间的时候就可以这样四个一组的计算,但是例如数据为 :
1 3 4 5这种方法就不对,这个时候要
1和5过河,1回来;
1和4过河,1回来;
最后1和3过河。
那么我们做题时就可以将这两种方法的时间都算出来,取最小的加到sum上,
当数据小于4个的时候我们就可以直接计算。

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[1001],t,n,i,sum;
int main()
{
    scanf("%d",&t);while(t--){
    sum=0;scanf("%d",&n);for(i=0;i<n;i++)scanf("%d",&a[i]);sort(a,a+n);while(n>=4){
    if(a[n-1]+a[0]+a[n-2]+a[0]<a[1]+a[0]+a[n-1]+a[1]){
    sum=sum+a[n-1];//a[0]和a[n-1]一起过去sum=sum+a[0];//a[0]回来sum=sum+a[n-2];//a[0]和a[n-2]一起过去sum=sum+a[0];//a[0]回来}else{
    sum=sum+a[1];//a[0]和a[1]一起过去sum=sum+a[0];//a[0]回来sum=sum+a[n-1];//a[n-2]和a[n-1]一起过去sum=sum+a[1];//a[1]回来}n=n-2;//一个循环处理两人次}if(n==1)sum=sum+a[0];if(n==2)sum=sum+a[1];else if(n==3)sum=sum+a[0]+a[1]+a[2];printf("%d\n",sum);}return 0;
}