51nod 贪心入门之四 独木舟问题
2017-02-26 14:11
274 查看
n个人,已知每个人体重,独木舟承重固定,每只独木舟最多坐两个人,可以坐一个人或者两个人。显然要求总重量不超过独木舟承重,假设每个人体重也不超过独木舟承重,问最少需要几只独木舟?
分析:
一个显然的策略是按照人的体重排序。
极端化贪心策略,最重的人要上船——如果最重的人和最轻的人体重总和不超过船的承重,则他们两个占用一条船。否则(因为假设最重的人的体重也不超过船的承重了),最重的人单独占一条船。转变为(n – 1)或者(n – 2)的问题了。
关键在于这种贪心策略是正确的。我们可以证明,最优解也可以变为这种策略。
(1) 假设最重的人和最轻的人的体重和超过了船的承重,那么最优解中,显然也是最重的人单独占一条船,所以这种情况下最优解和贪心策略是相同的。
(2) 假设最重的人和最轻的人的体重和没超过船的承重。
(2.1)如果最优解中,最重的人单独占用一条船,则可以把最轻的人也放上去,这样最优解用的船数不增加。如果最轻的人占用一条船,同样我们可以把最重的人放上去,最优解船数不增。
(2.2) 如果最优解中最重的人x和x’占用一只船(x, x’),而最轻的人y和y’占用一只船(y, y’)
我们换成(x, y) (x’,y’)
(x, y)显然没超过船的承重——因为我们假设就是如此。关键看(x’, y’)。
x’ + y’<= x’ + x 因为(x’, x)没超重,所以(x’,y’)也合法。所以换一下,最优解船数也不增。这样我们就证明了如果可能把最重的人和最轻的人放在一条船上,不会影响最优解。
反复应用这个策略,就可以把n降低为(n – 1)或者(n – 2)个人的规模,从而解决这个问题。
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
输入
输出
输入示例
输出示例
水水水。。。但还是WA了几发。。。
把while里条件改了就过了。。。
AC代码:
分析:
一个显然的策略是按照人的体重排序。
极端化贪心策略,最重的人要上船——如果最重的人和最轻的人体重总和不超过船的承重,则他们两个占用一条船。否则(因为假设最重的人的体重也不超过船的承重了),最重的人单独占一条船。转变为(n – 1)或者(n – 2)的问题了。
关键在于这种贪心策略是正确的。我们可以证明,最优解也可以变为这种策略。
(1) 假设最重的人和最轻的人的体重和超过了船的承重,那么最优解中,显然也是最重的人单独占一条船,所以这种情况下最优解和贪心策略是相同的。
(2) 假设最重的人和最轻的人的体重和没超过船的承重。
(2.1)如果最优解中,最重的人单独占用一条船,则可以把最轻的人也放上去,这样最优解用的船数不增加。如果最轻的人占用一条船,同样我们可以把最重的人放上去,最优解船数不增。
(2.2) 如果最优解中最重的人x和x’占用一只船(x, x’),而最轻的人y和y’占用一只船(y, y’)
我们换成(x, y) (x’,y’)
(x, y)显然没超过船的承重——因为我们假设就是如此。关键看(x’, y’)。
x’ + y’<= x’ + x 因为(x’, x)没超重,所以(x’,y’)也合法。所以换一下,最优解船数也不增。这样我们就证明了如果可能把最重的人和最轻的人放在一条船上,不会影响最优解。
反复应用这个策略,就可以把n降低为(n – 1)或者(n – 2)个人的规模,从而解决这个问题。
最后,我们来提供输入输出数据,由你来写一段程序,实现这个算法,只有写出了正确的程序,才能继续后面的课程。
输入
第一行包含两个正整数n (0<n<=10000)和m (0<m<=2000000000),表示人数和独木舟的承重。 接下来n行,每行一个正整数,表示每个人的体重。体重不超过1000000000,并且每个人的体重不超过m。
输出
一行一个整数表示最少需要的独木舟数。
输入示例
3 6 1 2 3
输出示例
2
水水水。。。但还是WA了几发。。。
把while里条件改了就过了。。。
AC代码:
#include<iostream> #include<algorithm> using namespace std; int main() { long long weight[10005] = { 0 }; long long boat, human, i; cin >> human >> boat; for (i = 0; i < human; i++) { cin >> weight[i]; } long long count = 0, j = 0; i = human-1; sort(weight, weight + human); while (j<=i) { if (i == j) { count++; break; } if (weight[i] + weight[j] <= boat) { count++; j++; i--; } else { count++; i--; } } cout << count << endl; return 0; }
相关文章推荐
- 51NOD - 贪心算法入门 - 独木舟问题 【简单贪心】
- [贪心入门]独木舟问题
- 贪心算法基础之独木舟问题 51nod 贪心教程
- 51nod贪心例子独木舟问题
- 51NOD - 贪心算法入门 - 活动安排问题 之 二【简单贪心 + 思维】
- 51Nod:独木舟问题(贪心)
- 51NOD - 贪心算法入门 - 活动安排问题 【简单贪心】
- 51nod 贪心入门之二 活动安排问题
- 51nod-独木舟问题
- 51nod 活动安排问题之二 (贪心+stl)
- 贪心入门2(活动安排问题)
- 51nod动态规划入门--编辑距离问题
- 51nod(动态规划入门---最大子段问题)
- 51nod 1428 活动安排问题(贪心)
- 51nod 独木舟问题
- 51Nod 活动安排问题之二(贪心)
- 【贪心+优先队列】1428 活动安排问题【51nod】【难度:2级算法题】
- 51nod贪心例子活动安排问题二
- 51NOD 最大子字段和问题(DP入门)
- 51nod 活动安排问题 (贪心)