还有一道比这道题更简单但是一样的题,忘了题号了,那题只求最少时间,实际上两题差不多,贪心策略
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; }