过河问题(贪心)nyoj47
2015-07-31 12:59
253 查看
描述 在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。 输入 第一行是一个整数T(1<=T<=20)表示测试数据的组数 每组测试数据的第一行是一个整数N(1<=N<=1000)表示共有N个人要过河 每组测试数据的第二行是N个整数Si,表示此人过河所需要花时间。(0<Si<=100) 输出 输出所有人都过河需要用的最少时间 样例输入 1 4 1 2 5 10 样例输出 17
解法一: /*#include<iostream> #include<cstdio> #include<algorithm> using namespace std; int time[1000]; int main() { int T,N,i,j,sum,sum1; scanf("%d",&T); while(T--) { sum=0,sum1=0; scanf("%d",&N); for(i=0;i<N;i++) { scanf("%d",&time[i]); } sort(time,time+N); if(N==1) sum=time[0]; if(N==2) sum=time[1]; if(N==3) sum=time[0]+time[2]+time[1]; while(N>3) { sum+=time[0]+2*time[1]+time[N-1]; //方案一:让最快的和第二快的先过去,然后最快的回来,让最慢的和倒数第二慢的人过去, // 然后让再让第二快的人回到原来位置。 sum1+=2*time[0]+time[N-2]+time[N-1]; //方案二:让最快的人来回做媒介,拿手电筒,然后回到原来位置; N-=2; //相当于每次只过去两个人,让最快的和第二快的回到原来的位置。 if(sum<sum1) sum=sum1; } printf("%d\n",sum); } return 0; }*/ 解法二: /*贪心。 解题思路: 当n==1或者n==2时:所有人直接过河即可。 当n==3时:用时最长和用时最短的人先一起过去,然后用时最短的人回来,再在和剩下的一个人一起过去。 当n==4时:假设time[0]为用时最短的人所用的时间,time[1]为用时第二短的人所用的时间, time[n-1]为用时最长的人所用的时间, time[n-2]为用时第二长的人所用的时间。则有两种过河方式: 2*time[0]+time[n-1]+time[n-2]表示:用时最长的人和用时最短的人先一起过去,然后用时最短的人把手电筒带回来,再和用时第二长的人一起过去,用时最短的人回来。 2*time[1]+time[0]+time[n-1]表示:用时最短和用时第二短的人一起过去,然后用时最短的人把手电筒带回来,然后用时最长和用时第二长的人一起过去,用时第二短的人回来。 比较两种过河方式:2*time[0]+time[n-1]+time[n-2]<2*time[1]+time[0]+time[n-1] 这样相当于每次都过去了两个人,所以n-=2, 再对剩下的n-2个人执行相同的操作,直至不足4人即可。 */ #include <cstdio> #include <algorithm> using namespace std; const int maxn = 1010; int time[maxn]; int n; int main() { int t,i,sum; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;++i) scanf("%d",&time[i]); sort(time,time+n); sum=0; while(n>=4) { if(2*time[0]+time[n-1]+time[n-2]<2*time[1]+time[0]+time[n-1])//比较两种过河模式 sum += 2*time[0]+time[n-1]+time[n-2]; else sum += 2*time[1]+time[0]+time[n-1]; n-=2; //每次计算最慢的两个人的过河时间 } if(n==3) sum += time[0] + time[1] + time[2]; if(n==2) sum += time[1]; if(n==1) sum += time[0]; printf("%d\n",sum); } return 0; }
相关文章推荐
- CDOJ 输出前m大的数据
- [转]DevExpress GridControl 关于使用CardView的一点小结
- QT下ui类的this指针与ui指针
- guava (四)--集合中的FluentIterable类
- AOP 切面编程
- bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化方法
- 数据库水平切分的实现原理解析---分库,分表,主从,集群,负载均衡器
- 关于 ART
- CDOJ Flagstone
- centos 配置Openssl并创建证书
- Xcode Version
- 【分享】 封装js操作textarea 方法集合(兼容很好)。
- Android开发周报: APK加壳技术、属性动画全解析
- common-dbcp.jar和commons-pool.jar引用和bug
- CentOS系统Nginx安装
- Docker网络功能
- 求数组中第一个无重复的元素
- Android 程序的安装、卸载和更新
- windows系统中安装配置tomcat
- POJ2891 Strange Way to Express Integers(解多元线性同余方程)