算法竞赛学习日记(1)——“贪心法”
来源:互联网 发布:淘宝的购物评级怎么涨 编辑:程序博客网 时间:2024/06/05 09:18
算法是不可能单纯的以方法来概括的,我觉得概括的只是一种人的基本想法而已。对于我这样的算法初学者,在碰到算法编程题的时候不知如何下手,只是有想法寥寥,而不知道应该以何种方法去做下去,所以手足无措。
贪心法——只顾眼前的利益,反而得到了最优的解。
这本来就是每个人在拿到一个算法题的时候会有的想法,所以归类方法的意义不在于身兼百种方法去一一与题目配对,而在于从一种想法入手,坚持尝试下去,从而真正的尝试出这种想法是否真正可行,而不要将想法一闪而过然后不知所措。
在《算法竞赛入门经典》这本书中,关于贪心法的乘船问题中,要求在每条船都有重量和人数限制的前提下,追求使用船的最少化问题。 同样是利用sort算法将人按照重量的大小来从小到大排序。
书中分析法我觉得自己很受用。我想的是最重的人要与之匹配能够乘船的重量最重的人绑定
这样的话我们将最重的人标记为i,将与i绑定的人的重量标记为j
用反证法来证明这种匹配方法是否为最优解
分两种情况:
1. i只自己坐一艘船,那么当i和j同坐一艘船的时候一定不会增加船的数量而且可能使其数量减少。
2. i与非j的另一人k同坐一船,k的重量一定比j要轻, 那么此时将j和k交换,这时候k所在的船不会超重,而i和j配对也不会超重,那么就不会增加船的数量,所以这种配对方法不会丢掉最优解….吗?
i只有这三种情况吗?
自己坐、与j坐、与j以外的另一个k坐。我会怀疑,会不会有这种情况的发生——有两只重量本来不算太重的船没有办法配对,而这些船也能够与j配对呢? 很可能会有,但这却不影响这道题的结果。 所以对于最后以船的数量作为一个指标,确实可以用这三种情况来框定,所以这样得到的解确实是最优解的一种。
然后我想这个算法要怎么来编写呢?
将重量数组从大到小排序,在遍历的时候,我们将当下最重的标记为i,与之可以配对的最重的人标记为j,配对之后,i++,那么j呢?
此时的J肯定要比之前的重,因为i轻了,那么对j就要执行j–喽?
然后直到i和j相碰的时候再返回去再去为i找第一次找到的j的地方之后去找更轻的?
哇,那这个编程真的有点麻烦了。
所以我觉得将sort算法的谓词设置为lessthan是有一定的道理的,有时候需要去按照原定的意思,于是有了书中的解法,为最轻的人i去配对与之可以配对的最重的人。
同样是反证法,而在遍历的时候要轻松的多,当i++之后,j比原来的j要轻了,所以j–,但是这时候的逻辑要清晰很多,那就是剩下的都好重啊,那就让他们一人坐一艘船呗。
int main(){ int n(0); scanf_s("%d\n", &n); const int max = 20000; int a[max] = {}; for (int i(0); i < n; i++) scanf_s("%d", &a[i]); sort(a, a + n); int k = n - 1; int total(0); int pairs(0); for (; k > 0; k--) { if ((a[0] + a[k]) <= 100) { pairs++; break; } } for (int i(1); i < k; i++) { for (int j(k - 1); j > i; j--) { if ((a[i] + a[j]) <= 100) { k = j; pairs++; break; // 这里我在编写的时候一直在想,如果针对某个i我找不到与之配对的j应该怎么跳出循环,后来我觉得我的思维又有点不机器化了。找不到也让它循环着,不动 k 也不动 pairs也照样能计算清楚 } } } total = n - pairs; printf("The number of ships is %d\n", total);}
- 算法竞赛学习日记(1)——“贪心法”
- 算法竞赛学习日记(2)——区间问题
- 算法竞赛学习笔记—田忌赛马(贪心法)
- 算法竞赛学习日记(3)——区间选点问题
- poj日记(1017)——贪心算法
- 算法学习笔记——贪心法
- 算法—贪心(1)
- 算法学习——贪心算法实践
- 索引—算法竞赛
- 算法竞赛入门经典——<1>
- 贪心算法——(1)
- 算法竞赛入门经典-学习笔记1(c语言)
- 算法竞赛入门经典学习笔记(1)
- 算法——贪心法
- javascript学习日记——(1)
- 【算法竞赛入门经典学习日记】第二章 循环结构程序设计
- 算法竞赛入门学习
- 贪心算法在竞赛中的应用
- ajax异步表单提交,并实现文件上传
- 欢迎使用CSDN-markdown编辑器
- include指令与include动作之间的区别
- 高并发解决方案
- double,float浮点型精确运算
- 算法竞赛学习日记(1)——“贪心法”
- NOIP2013 试做总结
- 链表的插入_删除
- 函数调用约定
- JAVA内存模型和线程安全
- 讯为Exynos4412开发板例程及注释——LED
- 【20170929】python_语言设计(1)基本语法
- 关于矩阵存在共线性的第二谈
- PKU 3281 Dining