题目
702:Crossing River
描述
A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat back and forth so that all people may cross. Each person has a different rowing speed; the speed of a couple is determined by the speed of the slower one. Your job is to determine a strategy that minimizes the time for these people to get across.
输入
The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. The first line of each case contains N, and the second line contains N integers giving the time for each people to cross the river. There won’t be more than 1000 people and nobody takes more than 100 seconds to cross.
输出
For each test case, print a line containing the total number of seconds required for all the N people to cross the river.
样例输入
1
4
1 2 5 10
样例输出
17
翻译
几人过河,只有一船,只能载2人。每次须得一个人把船开回来。划船时间算最慢人的时间。问最少时间都过河。
理解
基本能听懂,加上翻译也是学习过程。
1两个最快过去,最快开回来
2最慢两个开过去,次快开回来
所以一次可以去两人,用时次快*2+最快+最慢=t[2]2+t[1]+t[i]
这么想着就用双优先队列实现了,就是判断对岸没人就去最快的俩;有就去最慢的。模拟成功,顺便复习队列。可惜wrond。
搜索答案,才明白,还有种方案,要选优。
1.每次最快的带最慢的,开回来。
跟一方案结合,也是一次算去最慢两人,用时最快2+最慢+次慢=t[1]*2+t[i]+t[i-1]
代码
#include <bits/stdc++.h>
using namespace std;
int m,n,t[1010];
int main(){
//freopen(“in.cpp”,“r”,stdin);
cin>>m;
while(m–){
cin>>n;
for(int i=1;i<=n;i++)cin>>t[i];
if(n1){cout<<t[1]<<endl;continue;}
sort(t+1,t+n+1);
int he=0;
for(int i=n;i>3;i-=2)//四个人,走两人(-2),两种方案送优
he+=min(t[1]+2*t[2]+t[i],//先去两快,一人把船开回,再去两慢,次快把船开回
t[1]*2+t[i-1]+t[i]);//每次最快带最慢,要减两人
if(n%21)he+=t[1]+t[2]+t[3];//奇数人剩三人,5-2=3,两去回来带第三人,
else he+=t[2];//偶数剩两人,4-2=2一船
cout<<he<<endl;
}
return 0;
}
小结
不能臆想,还是要分析数据。
我的维度是一次过两人,只是考虑模拟实现第一种方案,没敢高纬俯瞰,没敢创设数据。