注意
例:指错误示例。
例题:指运用到那个思想或技巧的例题。
dp
- 背包:体积一定时价值最大,体积和价值可以替换成其他东西。
- 注意转移要从能转移的地方转移过来。(例)
- 树形 dp 注意别漏了父节点和父子节点之间的边。
- 树形 dp 一般是从下而上,遇到树形 dp 转移尽量从下往上想。
- 感觉做不了或感觉思路对但过不了就加状态或换状态。
- 感觉答案(或其他需要的东西)不能直接求出就加入状态一步一步求。(例题)
- 不优化做不了但只会暴力先写暴力(不管是 TLE 还是 MLE),再想优化。
- 各种优化:去掉不必要的循环(例题)、状态(例题);用等效的枚举(例题)替代暴力枚举;加状态(例题)。
贪心
- 一个常见思路:排序。
- 如果根据一个东西排序不好做,换一个。
位运算
- 如果题目上出现了位运算或 \(2^x\),那么正解很有可能与位运算有关。(例题 I、例题 II)
状态压缩
- 对于一个用二进制数表示的集合 \(S\),若要枚举它的所有非空子集 \(T\),可用以下代码:
for (int T=S;T;T=(T-1)&S) {/*do something ...*/}
优化
如果是 dp 的相关优化请去 dp 那一章节。
- 如果某个东西能预处理并且预处理后时间复杂度更优,一定要预处理。(我在某个比赛的现状:100pts \(\rightarrow\) 30pts)
- 空间如果需要优化,想想滚动数组。
- 小根堆尽量别用
priority_queue<...,vector<...>,greater<...> >
,要重载运算符(我喜欢这样搞,其他方法也是可以的),不然 T 都不知道怎么 T 的。 - 尽量少用模运算,这玩意特别慢。(优化前 and 优化后)
字符串
- 一些字符串处理题目可以用二叉树。(例题)
多测
- 记得清空。
- 小心卡常,不要滥用
memset
。 - 不要少输入了东西,也就是在输入时不要输一半就直接结束了。(很容易爆 \(0\))
找规律
- 打表是个好方法。
- 斐波那契数列。(例题)
- 杨辉三角。
精度
double
只能保证约前 \(15\) 位有效数字是准确的(多了会产生误差)。- 由于浮点数可能存在误差,所以要设一个极小数 \(eps\)(通常为 \(10^{-8}\) 左右),表示误差允许的范围。
- For example,判断 \(x\) 与 \(y\) 是否相等不能写成
x==y
,必须写成fabs(x-y)<eps
。
- For example,判断 \(x\) 与 \(y\) 是否相等不能写成
数据范围
y 总 yyds!!!
- 如果某个数的范围比其他数明显要小,那么正解很有可能和这个数有关。
- 注意爆
int
或爆long long
。(例题)
搜索
- 如果边权是 \(1\),并且是求最短路径,可以考虑一下 bfs。(例题)
- bfs 记得别走重了。(例)
图论
- 注意重边和自环。
别判错了(例) - 题中的条件是否可以转化为图论中的边。(例题 I、例题 II)
- 稠密图要用朴素 Prim 算法,稀疏图要用堆优化 Prim 算法。
- 注意图的连通性对答案的影响。
其他
- 对题目进行灵活转化。(例题)
- 不要把题目想难了,不然弱智题都做不出来。
- 正难则反。(例题)
- 注意一个地方的修改对其他地方的影响。(例)
- 不要把题目复杂化了。(例子:本来 bfs 能做的题用 dijkstra
那个人就是我) INF
尽量开大(如0x3f3f3f3f
),直接算可能的最大值可能会犯唐算错。(我的经历:100pts->80pts)- 注意对特殊情况的处理。(例)
- 注意各种奇葩的判重。(例题)
- 认真分析,不要“感觉是对的”。(例)
- 注意审题。(例)
- 注意思考对每一种情况的处理。
- 如果某种特殊的处理方式对某种特殊的数据来说是正确的,那么正解可能是这种处理方式的普遍化。(例题)
- 看到区间和想想是否可以转化成两个前缀和的差。
- 题上有提到关于二进制的东西(如异或)想想二进制拆分。