NYOJ47——过河问题(贪心)
2013-04-11 19:20
274 查看
题目描述:
在漆黑的夜里,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
思路分析:
那么这时将单独过河所需要时间最多的两个旅行者送到对岸去,有两种方式:
1、 最快的(即所用时间t[0])和次快的过河,然后最快的将船划回来,再次慢的和最慢的过河,然后次快的将船划回来,
2、 最快的和最慢的过河,然后最快的将船划回来,再最快的和次慢的过河,然后最快的将船划回来。
这样就将过河所需时间最大的两个人送过了河,而对于剩下的人,采用同样的处理方式,接下来做的就是判断怎样用的时间最少,
1、方案1所需时间为:t[0]+2*t[1]+t[i-1]
2、方案2所需时间为:2*t[0]+t[i-2]+t[i-1]
如果方式1优于方式2,那么有:t[0]+2*t[1]+t[i-1]<2*t[0]+t[i-2]+t[i-1] 化简得:2*t[1]<t[0]+t[i-2]。即此时只需比较2*t[1]与t[0]+t[i-2]的大小关系即可确定最小时间,此时已经将单独过河所需时间最多的两个人送过了河,那么剩下过河的人数为:i-=2,采取同样的处理方式。
如果没过河的人中,除了最快和次快的,就只剩下一个人,那么就由最快的送最慢的过河,最快的回来,最后最快的和次快的一起过河。时间为a[0]+a[i]。最后统一再加上最快和次快的过河时间。
参考代码:
在漆黑的夜里,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
思路分析:
那么这时将单独过河所需要时间最多的两个旅行者送到对岸去,有两种方式:
1、 最快的(即所用时间t[0])和次快的过河,然后最快的将船划回来,再次慢的和最慢的过河,然后次快的将船划回来,
2、 最快的和最慢的过河,然后最快的将船划回来,再最快的和次慢的过河,然后最快的将船划回来。
这样就将过河所需时间最大的两个人送过了河,而对于剩下的人,采用同样的处理方式,接下来做的就是判断怎样用的时间最少,
1、方案1所需时间为:t[0]+2*t[1]+t[i-1]
2、方案2所需时间为:2*t[0]+t[i-2]+t[i-1]
如果方式1优于方式2,那么有:t[0]+2*t[1]+t[i-1]<2*t[0]+t[i-2]+t[i-1] 化简得:2*t[1]<t[0]+t[i-2]。即此时只需比较2*t[1]与t[0]+t[i-2]的大小关系即可确定最小时间,此时已经将单独过河所需时间最多的两个人送过了河,那么剩下过河的人数为:i-=2,采取同样的处理方式。
如果没过河的人中,除了最快和次快的,就只剩下一个人,那么就由最快的送最慢的过河,最快的回来,最后最快的和次快的一起过河。时间为a[0]+a[i]。最后统一再加上最快和次快的过河时间。
参考代码:
#include<stdio.h> #include<stdlib.h> int compare(const void *a,const void *b) { int *p1 = (int *)a; int *p2 = (int *)b; return *p1-*p2; } int main() { int a[1000]; int n; int t; int i; int ans; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i = 0; i < n; ++i) scanf("%d",&a[i]); qsort(a,n,sizeof(int),compare); if(n < 3) { printf("%d\n",a[n - 1]); continue; } i = n - 1; ans = 0; while(i > 1) { if(i == 2) { //剩一个人,则最快的把最慢的送过去 ans += a[0] + a[i]; break; } if(a[1] + a[1] < a[i - 1] + a[0]) ans += a[i] + a[1] + a[1] + a[0]; else ans += a[i] + a[i - 1] + a[0] + a[0]; i -= 2; } //最后把最快的和最慢的送过河 ans += a[1]; printf("%d\n", ans); } }
相关文章推荐
- nyoj 47 过河问题 【贪心】
- nyoj 47 过河问题 贪心
- NYOJ_47 过河问题,贪心选择
- NYOJ 47-过河问题(贪心)
- nyoj47过河问题(贪心)
- NYOJ 47 过河问题(贪心)
- NYOJ 题目47 过河问题 (贪心)
- 过河问题(贪心)nyoj47
- NYOJ 47 过河问题 (贪心)
- NYOJ-47 过河问题(贪心)
- nyoj 47 过河 过河问题 【贪心】
- POJ-1700 &&NYOJ 47 过河问题【贪心】
- NYOJ 47 过河问题 (贪心)
- 贪心算法之——过河问题(nyoj47)
- nyoj47过河问题(贪心)
- NYOJ 47 过河问题 (贪心)
- nyoj 47 过河问题(贪心)
- nyoj 47 过河问题(贪心)
- Nyoj 47 过河问题
- NYOJ 47 过河问题