openjudge4.6算法之贪心——702:Crossing River

文章讲述了在一个限制条件下,如何通过最优策略安排让一组人过河,同时确保总时间最小化的具体方法。涉及算法设计和时间复杂度分析。
摘要由CSDN通过智能技术生成

题目

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%2
1)he+=t[1]+t[2]+t[3];//奇数人剩三人,5-2=3,两去回来带第三人,
else he+=t[2];//偶数剩两人,4-2=2一船
cout<<he<<endl;
}
return 0;
}

小结

不能臆想,还是要分析数据。
我的维度是一次过两人,只是考虑模拟实现第一种方案,没敢高纬俯瞰,没敢创设数据。

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值