一个一定要好好提溜出来的贪心题
题意描述: 有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-