枚举是一种常见的算法,通过各种技巧可以优化枚举次数。 【POJ 3061】Subsequence(尺取法): 给定一个长度为 \(n\) 的数列 \(a\),找到最短的区间 \([l,r]\),使得 \(\sum\limits_{i=l}^{r}a_i \ge S\)。\(1 \le n \le 10^5, 1 \le S \le 10^8\)。 这道题的朴素做法是枚举所有区间,时间复杂度约为 \(\mathcal{O}(n^2)\)。但实际上没有必要枚举所有区间,我们可以采用尺取法。首先观察题目,假设我们找到了一个区间 \([l,r]\),区间和 \(\sum\limits^{r}_{i=l}a_i \ge S\),既然区间和已经 \(\ge S\) 了,我们继续往后区间仍然会 \(\ge S\),且一定不是最优解,因此我们可以枚举 \(l\),对于每个 \(l\) 不断把 \(r\) 往后移,直到 \(\sum\limits^{r}_{i=l}a_i \ge S\) 为止,用 \(ans\) 统计最短的区间 \([l,r]\),当 \(l\) 更新时我们就不断后移 \(r\),这样我们就减少枚举了很多不可能是答案的区间,时间复杂度约为 \(\cal{O}(n)\)。 模拟是一种常见的算法,往往思维难度不大,但十分考察选手的细心程度、处理问题的能力。有的较难的模拟可以通过一些技巧来优化。 从名字很好理解,两个端点进行枚举。 博览馆正在展出由世上最佳的 \(m\) 位画家所画的图画。 游客在购买门票时必须说明两个数字,\(a\) 和 \(b\),代表他要看展览中的第 \(a\) 幅至第 \(b\) 幅画(包含 \(a,b\))之间的所有图画,而门票的价钱就是一张图画一元。 Sept 希望入场后可以看到所有名师的图画。当然,他想最小化购买门票的价格。 请求出他购买门票时应选择的 \(a,b\),数据保证一定有解。 若存在多组解,输出 \(a\) 最小的那组。 维护区间 \([l,r]\),不断后移 \(r\),并且用桶记录所有画家的画出现的次数,当所有画家都有的时候更新答案,并把 \(l\) 后移(类似尺取法),最终求出最佳答案。 练习:枚举
模拟
双指针
前缀和 & 差分