题目链接:传送门
思路:大致题意就是n个人过桥时间有快慢,每次只能两个人过,n个人中只有一个手电筒,每次都得拿着手电筒才能过桥,意思就是两个人过去之后,还要回来送手电筒,让我们找一种策略让所有人最短时间内通过,输出最短时间以及过得的策略。
t时间,每个人过桥的时间由小到大排序
- n=1时,直接过去,t=a[0]
- n=2时,直接过去,t=max(a[0],a[1]),也就是t=a[1]
- n=3时,假设ABC三人策略1:AC,A,AB和AB,A,AC,两种策略所用时间相同t=a[0]+a[1]+a[2]
- n>=4时,假设a[0~n-1](下标从0到n-1共n个人)
一种策略:a[0]和a[n-1]过桥,a[0]回来送手电筒,a[0]和a[n-2]过桥,a[0]回来,至此没过去的还有a[0],a[1].....a[n-3],
然后n-=2(因为已经过去了最后两个人,还剩n-2人),循环一直让最快的(a[0])把最后的两个人送过去,再回来,直到n<4
另一种策略:让a[0]和a[1]先过去,a[0]回来,再让a[n-1]和a[n-2]过去,a[1]回来(过去的最小的回来),n-=2,循环,直到n<4
代码实现:主要说明循环里如何操作(因为这个有点难想想)
while(n>=4){
if(a[n-1]+2*a[0]+a[n-2]>=a[n-1]+2*a[1]+a[0])
{
//ans+=a[n-1]+2*a[1]+a[0];
cout<<a[0]<<" "<<a[1]<<endl<<a[0]<<endl<<a[n-2]<<" "<<a[n-1]<<endl<<a[1]<<endl;
}else{
//ans+=a[n-1]+2*a[0]+a[n-2];
cout<<a[0]<<" "<<a[n-1]<<endl<<a[0]<<endl<<a[0]<<" "<<a[n-2]<<endl<<a[0]<<endl;
}
n-=2;
}
以上就是解决人数超过4人的两种选择方案:a[n-1]+2*a[0]+a[n-2]>=a[n-1]+2*a[1]+a[0]
我们把n个人先抽出前两个和最后两个AB,YZ,策略1是AB,A,YZ,B或者策略2是AZ,A,AY,A
即:策略1所需时间a[n-1]+2*a[1]+a[0],策略2所需时间:a[n-1]+2*a[0]+a[n-2]
其目的就是把最后两个人送到桥那边,这边还有A,B和剩下的n-4个人,那么进行循环的条件就是继续把桥这边的最后两个人送过去,知到n<4,所以策略1和策略2相比较我们只选择最优解即可
code :ac代码
#include<iostream>
#include<algorithm>
using namespace std;
int a[1005];
int f(int n){//递归实现总时间的输出
if(n==1)return a[0];
else if(n==2)return a[1];
else if(n==3)return a[0]+a[1]+a[2];
else
{
if(a[n-1]+2*a[0]+a[n-2]>=a[n-1]+2*a[1]+a[0])
return a[n-1]+2*a[1]+a[0]+f(n-2);
else
return a[n-1]+2*a[0]+a[n-2]+f(n-2);
}
}
int main()
{
int t,n,flag=0;//flag换行的作用
cin>>t;
while(t--){
if(flag)cout<<endl;//第一个组测试数据不换行,之后每组换行
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
cout<<f(n)<<endl;
while(n>=4){
if(a[n-1]+2*a[0]+a[n-2]>=a[n-1]+2*a[1]+a[0])
{
//ans+=a[n-1]+2*a[1]+a[0];
cout<<a[0]<<" "<<a[1]<<endl<<a[0]<<endl<<a[n-2]<<" "<<a[n-1]<<endl<<a[1]<<endl;
}else{
//ans+=a[n-1]+2*a[0]+a[n-2];
cout<<a[0]<<" "<<a[n-1]<<endl<<a[0]<<endl<<a[0]<<" "<<a[n-2]<<endl<<a[0]<<endl;
}
n-=2;
}
if(n==3){
cout<<a[0]<<" "<<a[1]<<endl<<a[0]<<endl<<a[0]<<" "<<a[2]<<endl;
}
if(n==2)
cout<<a[0]<<" "<<a[1]<<endl;
if(n==1)
cout<<a[0]<<endl;
flag=1;
}
return 0;
}
总结:以上到这基本上就完了,最后注意一下换行的输出(第一组数组不换行,其后每组数据都换行)