1 骗分——与复杂度的较量

文章探讨了在程序优化和信息学竞赛中如何降低编程复杂度,以达到最佳得分效率。作者指出,降低时间复杂度并不总是最佳策略,有时牺牲部分时间复杂度以节省编程时间更为合理。在选择算法时,应考虑题目难度、比赛类型和个人目标,例如在NOIP中可能选择确保得分的算法,而在NOI中则追求更高分的解决方案。此外,文章强调常数因子的重要性,提醒程序员关注算法的实际运行时间,并提倡根据比赛时限有效利用CPU指令。
摘要由CSDN通过智能技术生成
        从本质上说,“程序优化”就是降低时间复杂度 3 的过程。而“骗分”,则是 降低编程复
杂度 的过程,更准确的说,是 取得得分与编程时间的最优比值
        有人会问,如果这道题根本不会做,连算法都没有,谈何“降低时间复杂度”?其实不
然。对于任何问题,只要它是一个 可解问题 ,就一定可以通过枚举法来解决。即使是 NPC
问题 ,只要将所有可能的情况一一列举,都能在有限时间(不论它有多长)中解决。所以
从理论上说,可解问题都有最低时间复杂度。
        但在实际编写程序时,我们不能让程序运行 1 年甚至更长,于是需要更为高效的算法。
我们信息学竞赛学习如此众多的算法、优化技巧,说到底,就是在降低程序运行的时间复杂
度,使得程序在规定时间内出解。正是基于这样的观点,本文的各种算法都关注了时间复杂
度的衡量,而且不同于理论著作,更加注重实际运行时间的比较,因为理论复杂度不能说明
一切问题,应试中的时限才是硬道理。
        要纠正一种错误的观念,“时间复杂度越低越好 ”。有时为了降低一道题目的复杂度,
耽误了其他题目解决的时间,得不偿失;这时不如放弃这道题目的进一步优化,争取得到
50-60 分,再去解决其他题目。这种策略尤其对于难题、高档次考试有效。另外,复杂度记
号中的常数因子也是不可忽略的。例如搜索中剪枝本身的代价超过被剪掉的搜索代价,就不
如不剪。这也提醒我们,养成良好的编程习惯,降低常数复杂度,也是“骗分”的重要手段。
在信息学竞赛中,“ 用空间换时间 ”是常用的策略。这里我们再提出一个观点: 用运行
时间换编程时间 用尽时限 中的每个 CPU 指令。
        考虑一个问题:有 O(nlogn) 7 A 算法但需要 200 行代码,而有 O(n 2 ) B 算法只需要
70 行代码,而对于 60% 的数据, n<1000 ;对于 100% 的数据, n<100000. 我们需要做出一个
决策。采用 A 算法,至少得 60 分,可能用掉 40 分钟;采用 B 算法, 100 分到手,可能用
100 分钟。对于 不同类型的比赛 ,我们应有不同的决策。对于 NOIP 这种其他题目较为简
单、这样的试题是压轴题的情况,可以先做其他简单试题,最后视剩下时间长短选择算法;
而对于 NOI 这种“难题集萃”类型的试题,如果其他试题没有思路,可以用较长的时间完
全解决该题;否则两道 60 分的题胜过一道 100 分的题。
当然,算法的选择还与选手的 竞赛目标 有关。期望拿到 NOIP 一等奖或 NOI 银牌的选
手可能希望尽量多得分,实力也不是很强,能得一分算一分,这样应选择 60 分的算法,以
“保险”为基础;期望进入省队或国家集训队的选手必须发挥出色,编程水平较高,这样应
选择 100 分的算法,拉大与其他选手的差距。
        总而言之,算法的选择与“得失”的衡量有关,这样本文所述的“用运行时间换编程时
间”就是正确的。例如 NOIP1999 第四题“拦截导弹”,要求输出最长不升子序列。这道题
O(n *n ) 的动态规划算法,也有 O(nlogn) 的基于二分搜索的算法。但原题 n<=1000 ,就没有
必要使用较为复杂且调试困难、容易出错的 log 级算法。所以,盲目优化时间复杂度不是可
取的行为。运用这些时间,可以解决其他问题,得到更高的分数。我们的目的,就是找到“时
时间复杂度表示式中隐藏的常数因子不可忽略,尤其是对于搜索类题目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值