poj 2573 bridge

Bridge
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3500 Accepted: 1234 Special Judge

Description

n people wish to cross a bridge at night. A group of at most two people may cross at any time, and each group must have a flashlight. Only one flashlight is available among the n people, so some sort of shuttle arrangement must be arranged in order to return the flashlight so that more people may cross. 
Each person has a different crossing speed; the speed of a group is determined by the speed of the slower member. Your job is to determine a strategy that gets all n people across the bridge in the minimum time. 

Input

The first line of input contains n, followed by n lines giving the crossing times for each of the people. There are not more than 1000 people and nobody takes more than 100 seconds to cross the bridge.

Output

The first line of output must contain the total number of seconds required for all n people to cross the bridge. The following lines give a strategy for achieving this time. Each line contains either one or two integers, indicating which person or people form the next group to cross. (Each person is indicated by the crossing time specified in the input. Although many people may have the same crossing time the ambiguity is of no consequence.) Note that the crossings alternate directions, as it is necessary to return the flashlight so that more may cross. If more than one strategy yields the minimal time, any one will do.

Sample Input

4
1
2
5
10

Sample Output

17
1 2
1
5 10
2
1 2

稍作分析,慢成员需要借助快成员传递手电筒。

思想是每次送两个最慢的人过桥,那么就有下面两种情况可能使时间最短,第一种是总是让时间最短的人去递手电筒,依次把两个最慢的人送过桥。第二种

是首先最快的和次快的过去,然后最快的人回来,最慢的人和次慢的人过去,次快的人回来。

假设用时最短为A,次短为B,用时最长为a,次长为b。(a和b每次都会变,假若先把最慢的人和次慢的人送过桥了,那么下一次第三慢的人就成了最慢的了,

第四慢 的人,也就成了次慢的。依次类推)

那么第一种方案用的时间为 A*2 + a+b

第二种方案用的时间为2*B + A + a

那么只需比较A*2 + a + b 与 2*B + A + a的大小了

最后注意一下边界。还有输入1的情况(博主被这个坑了好久)


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>

using namespace std;
#define maxn 1005
#define inf 0x7ffffff
int arr[maxn];
int n;
int main()
{
    scanf("%d",&n);
    for(int i = 0; i < n;i++){
        scanf("%d",&arr[i]);
    }
    if(n == 1){
        printf("%d\n%d\n",arr[0],arr[0]);
        return 0;
    }
    sort(arr,arr+n);
    int tmp = n -1;
    int ans = 0;
    while(tmp > 2){
        if(arr[0] + arr[tmp -1] < 2 * arr[1]){
            ans += arr[0] * 2 + arr[tmp-1] + arr[tmp];
        }else{
            ans += 2*arr[1] + arr[0] + arr[tmp];
        }
        tmp -= 2;
    }
    if(tmp == 2){
        ans += arr[0] + arr[1] + arr[2];
    }else{
        ans += arr[1];
    }
    printf("%d\n",ans);

    tmp = n -1;
    while(tmp > 2){
        if(arr[0] + arr[tmp -1] < 2 * arr[1]){
            printf("%d %d\n%d\n%d %d\n%d\n",arr[0],arr[tmp],arr[0],arr[0],arr[tmp-1],arr[0]);
        }else{
            printf("%d %d\n%d\n%d %d\n%d\n",arr[0],arr[1],arr[0],arr[tmp-1],arr[tmp],arr[1]);
        }
        tmp -= 2;
    }
    if(tmp == 2){
        printf("%d %d\n%d\n%d %d\n",arr[0],arr[2],arr[0],arr[0],arr[1]);
    }else{
        printf("%d %d\n",arr[0],arr[1]);
    }
    return 0;
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值