一个一定要好好提溜出来的贪心题

poj1700 Crossing River

题意描述: 有N个人要渡河,但是只有一艘船,船上每次最多只能载两个人,渡河的速度由两个人中较慢的那个决定,小船来回载人直到所有人都渡河,求最短的渡河时间。

输入:

输入有T组数据:

每组数据第一行为一个n,表示共有n个人;

第二行包含n个整数,为每个人的过河时间p。n≤1000,p[i]≤100;

输出:

对于每组测试数据,输出一行s,表示所有n个人过河所需的总时间;

先看样例:

首先解释样例:

1~2过河,1送回来;

5~10过河,2送回来;

1~2过河;

直觉:最慢两人要搭伙过河;

设AB为最快的,CD为最慢的

把CD送过河的两种方案:

取楼上两种方法的最小值;

将CD送过河之后,变成子问题;人数每次减2;

减到最后,有两种情况:

1.四个人,直接在进行楼上的操作,最后不要忘记再加上把AB送过河的p[B];

2.三个人,A来回送叭:

然后不知道是不是我太菜了,我交了8遍,很多细节都没考虑到:

 都是一些细节性的脑抽性的错误,也是很令人质壁分离啦:

一定要记得特判n==1和n==2的情况呀!

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long

using namespace std;

inline int read(){
    int ans=0;
    char last=' ',ch=getchar();
    while(ch>'9'||ch<'0') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}

int n,p[1010],num;
int ans;
bool cmp(int a,int b){
    return a<b;
}

int main(){
    int T;
    T=read();
    int nowr,nowl;
    while(T--){
        n=read();
        ans=0;
        memset(p,0,sizeof(p));
        num=n;
        for(int i=1;i<=n;i++)
            p[i]=read();
        sort(p+1,p+n+1,cmp);
        if(n==1){
            printf("%d\n",p[1]);
            continue;
        }
        if(n==2){
            printf("%d\n",p[2]);
            continue;
        }
        nowr=n;nowl=n-1;
        while(1){
            if(num<=4) break;
            ans+=min(p[nowl]+p[nowr]+2*p[1],p[nowr]+2*p[2]+p[1]);
            nowr-=2;nowl-=2;num-=2;
        }
        if(num==3) ans+=p[1]+p[2]+p[3];
        if(num==4) ans+=min(p[3]+p[4]+2*p[1],p[4]+2*p[2]+p[1]),ans+=p[2];;
        
        printf("%d\n",ans);
    }
    
    return 0;
}

end-

posted @ 2019-07-24 06:51  Sweetness  阅读(239)  评论(0编辑  收藏  举报