原文
https://www.quora.com/What-is-the-most-interesting-problem-solving-technique-or-trick-in-programming-contest
我在辅导学生时,经常会遇到这样的情况:如果一个问题乍一看学生就觉得不清楚,他们就无法解决它。事实上,你总是听到关于特定方法和技巧的信息。但你没有听到如何去思考才能应用它们。在这篇文章中,我将尝试总结我解决编程竞赛问题的一些经验。然而,其中的一些建议也适用于数学奥林匹克竞赛和你在学术研究中的第一步。
所以你已经读过了一个问题,但不知道如何解决。试试以下的技巧,其中一些经常派上用场。
试着回忆一些你曾经解决过类似的问题。很多问题并不是全新的想法。因此,你可能可以利用你解决类似问题经验来解决这个问题。
假设你已经找到了这个问题的解决方案(太棒了!)。让我们考虑一下这个问题的一个具体情况。当然,你可以将算法/解决方案应用于它。这就是为什么,为了解决一个一般问题,你需要解决它所有特定的情况。试着解决一些(或多个)特定的情况,然后尝试概括成整体问题解决方案。这些特定的情况可以看作是问题的简化,也就是说,我们可以根据以下原则推理:“如果我不知道如何解决一个复杂的问题,我想我会简化它并找到简化版本解决方案”。
流行的简化例子(特定情况):
你得到一个树的问题。考虑它的变体,树退化为一条路径;
问题有权重?考虑所有权重都等于 1 或一个任意数字,或者只有两个不同的权重(等等)。
请注意,解决一个特定情况几乎总是比解决一个一般情况更难,所以你需要尝试找到一个尽可能简单有效的解决方案。
不要羞于提出你认为正确的、大胆的假设。你不必在比赛中证明你的解决方案,发挥你的直觉。当你提出你的假设后,试着去证明它——它可能会奏效,也可能会给你一个如何反驳它的想法。在广泛的测试集上测试你的假设,因为它在实现一个基于假设的解决方案然后才反驳假设上浪费时间会很痛苦。
例子:
解决方案总是存在的;
状态的数量不大。
我是认真的,把自己放到问题人物的位置,想象成你的工作是处理输入集。想想在这种情况下你会怎么做。试着自己处理一些小的样本。如果问题是关于一个游戏,那就玩。有时我会尝试可视化一个过程或模型以便更好地理解。这有点像电影展示科学家思考方式的样子。试着图像化思考,想象解决方案,看到它的展开。
这个技巧只适用于团队赛。两人或三人小组开始说出一些关于问题的信息。例如:“如果 n 是偶数,那么答案总是 0”,“如果 n 是质数,那么解决方案应该这样”,等等。有时你的队友会抓住这些想法并发展它们,这个策略可以帮助你解决问题。
尝试使用任何可以应用于该问题的流行算法或方法。看到问题的限制很有用。选择了一个方法后,试着假设问题已经使用这个方法解决了来思考解决方案。你的推理应该是这样的:“假设这个问题是通过分治解决的。那么让我们递归地为左半部分和右半部分解决这个问题。现在剩下的就是找到一个将这些解决方案统一起来的方法。我想知道我们怎么做才能做到这一点…”
通常(尤其是在输入数据很小的问题:一个/两个数字)问题解决方案的组成中会有一些模式。为了看到一个模式,有时你需要编写一些解决问题的简单方法,针对大量测试在大限制下生成答案,然后花一段时间冥想你的答案。为了不占用计算机,一个好的策略是打印出获取的结果,然后这次在打印输出上进行冥想。
有时不仅打印答案,而且打印一些额外的信息也是个好主意,例如获取解决方案的方式。