还有一道比这道题更简单但是一样的题,忘了题号了,那题只求最少时间,实际上两题差不多,贪心策略
1、让划船划的最快的人依次与最慢的两人组队去对面,然后他在把船划回来,这样到对岸的时间花费很多,但是回来的时间少。
2、先让最快的两人去对岸,然后让其中一人把船划回来,再让最慢的两人组队去对岸,让先前还剩下那人把船划回来,这样使得到对岸的时间减少了,但是划回来的时间增多了。
依靠上面两个贪心策略,执行一次后得到的状态都是相等的,于是可以递归解决,每次进行比较,看哪种贪心策略更优,直到要过河的人小于4
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int po[1005];
int ans[4000],top,ti;
void dfs(int left,int right)
{
if(left>right)
return ;
else if(left==right)
{
ti+=po[left];
ans[top++]=po[left];
}
else if(left+1==right)
{
ti+=po[right];
ans[top++]=po[left];
ans[top++]=po[right];
}
else if(left+2==right)
{
ti+=po[right]+po[right-1]+po[left];
ans[top++]=po[left];
ans[top++]=po[right];
ans[top++]=po[left];
ans[top++]=po[left];
ans[top++]=po[left+1];
}
else
{
int tp1=po[right]+2*po[left]+po[right-1];
int tp2=po[left]+po[left+1]*2+po[right];
if(tp1<=tp2)
{
ti+=tp1;
ans[top++]=po[left];
ans[top++]=po[right];
ans[top++]=po[left];
ans[top++]=po[left];
ans[top++]=po[right-1];
ans[top++]=po[left];
}
else
{
ti+=tp2;
ans[top++]=po[left];
ans[top++]=po[left+1];
ans[top++]=po[left];
ans[top++]=po[right-1];
ans[top++]=po[right];
ans[top++]=po[left+1];
}
dfs(left,right-2);
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%d",&po[i]);
sort(po,po+n);
ti=top=0;
dfs(0,n-1);
printf("%d\n",ti);
for(int i=0;i<top;i+=3)
{
if(i+2==top)
printf("%d %d\n",ans[i],ans[i+1]);
else if(i+1==top)
printf("%d\n",ans[i]);
else
printf("%d %d\n%d\n",ans[i],ans[i+1],ans[i+2]);
}
}
return 0;
}