Loading docs/basic/binary.md +2 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ 它每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需要到右侧去找就好了;如果中间元素大于所查找的值,同理,右侧的只会更大而不会有所查找的元素,所以只需要到左侧去找。 在二分搜索过程中,每次都把查询的区间减半,因此对于一个长度为 $n$ 的数组,至多会进行 $\mathcal {O}(\log n)$ 次查找。 在二分搜索过程中,每次都把查询的区间减半,因此对于一个长度为 $n$ 的数组,至多会进行 $O(\log n)$ 次查找。 ```c++ int binary_search(int start, int end, int key) { Loading docs/dp/index.md +11 −11 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ $$ ### 最长回文子串 $O(n^2)$:$dp[i] = \max(dp[j] + 1), s(j + 1 .. i)$ 是回文 $O(n^2)$:$dp[i] = \max(dp[j] + 1), s(j + 1 \cdots i)$ 是回文 $O(n)$: Manacher Loading @@ -139,9 +139,9 @@ $p[i]$ 表示从 $i$ 向两侧延伸(当然要保证两侧对应位置相等 这样得到的回文串长度就保证是奇数了 考虑如果按顺序得到了 $p[1 .. i - 1]$,如何计算 $p[i]$ 的值? 考虑如果按顺序得到了 $p[1 \cdots i - 1]$,如何计算 $p[i]$ 的值? 如果之前有一个位置比如说是 $id$,有 $p[id] + id > i$ 那么 $i$ 这个位置是被覆盖了的,根据 $id$ 处的对称性,我们找 $p[id * 2 - i]$ 延伸的部分被 $p[id]$ 延伸的部分所覆盖的那段,显然这段对称回去之后是可以从 $i$ 处延伸出去的长度。 如果之前有一个位置比如说是 $id$,有 $p[id] + id > i$ 那么 $i$ 这个位置是被覆盖了的,根据 $id$ 处的对称性,我们找 $p[id \times 2 - i]$ 延伸的部分被 $p[id]$ 延伸的部分所覆盖的那段,显然这段对称回去之后是可以从 $i$ 处延伸出去的长度。 如果找不到呢?就先让 $p[i] = 1$ 吧。 Loading @@ -167,19 +167,19 @@ upd:其实是[程设期末推荐练习](https://ir1d.cf/2018/06/23/cssx/程设 #### 思路一: $dp[i][j] \ 表示\ 1..i\ 和\ 1..j\ 两条路径$。 $dp[i][j]$ 表示 $1 \cdots i$ 和 $1 \cdots j$ 两条路径。 我们可以人为要求 $1..i$ 是更快的那一条路径。 我们可以人为要求 $1 \cdots i$ 是更快的那一条路径。 这样考虑第 $i$ 个点分给谁。 如果是分给快的那条: $dp[i][j] = \min(dp[i - 1][j] + dis[i - 1][i]),\ j = 1..i$ $dp[i][j] = \min(dp[i - 1][j] + dis[i - 1][i]),\ j = 1 \cdots i$ 如果是慢的,原来是慢的那条就变成了快的,所以另一条是到 $i - 1$ 那个点: $dp[i][j] = \min(dp[i - 1][j] + dis[j][i]),\ j = 1..i$ $dp[i][j] = \min(dp[i - 1][j] + dis[j][i]),\ j = 1 \cdots i$ 答案是 $\min(dp[n][i] + dis[n][i])$。 (从一开始编号,终点是 $n$) Loading @@ -188,9 +188,9 @@ $dp[i][j] = \min(dp[i - 1][j] + dis[j][i]),\ j = 1..i$ #### 思路二 把 $dp[i][j]$ 定义反过来,不是 $1..i$ 和 $1..j$。 把 $dp[i][j]$ 定义反过来,不是 $1 \cdots i$ 和 $1 \cdots j$。 改成是 $i..n$ 和 $j..n$,不要求哪个更快。 改成是 $i..n$ 和 $j \cdots n$,不要求哪个更快。 这样的转移更好写: Loading Loading @@ -269,7 +269,7 @@ ref:https://segmentfault.com/a/1190000008720143 限制:要求相邻两行中删除的像素必须位于同一列或相邻列。 $dp[i][j] = \min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + cost[i][j]$ $dp[i][j] = \min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + cost[i][j]$ 边界:$dp[1][i] = cost[1][i]$。 Loading @@ -279,7 +279,7 @@ $dp[i][j] = \min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + cost[i][j 等价于之前那个最优二叉搜索树。 $dp[i][j] = \min(dp[i][k] + dp[k][j]) + l[j] - l[i] + 1,\ k = i + 1\ ..\ j - 1$ $dp[i][j] = \min(dp[i][k] + dp[k][j]) + l[j] - l[i] + 1,\ k = i + 1 \cdots j - 1$ 注意 $l[i]$ 表示的是第i个切分点的位置。 Loading docs/dp/memo.md +3 −4 Original line number Diff line number Diff line Loading @@ -8,9 +8,9 @@ by $\color{Gray}{InterestingLSY}$ (菜到发灰) ## 1. 记忆化搜索是啥 好,就以 [这道题](https://www.luogu.org/problemnew/show/P1048) 为例,我不会动态规划,只会搜索,我就会直接写一个粗暴的 [DFS](/search/dfs) : 好,就以 [洛谷 P1048 采药](https://www.luogu.org/problemnew/show/P1048) 为例,我不会动态规划,只会搜索,我就会直接写一个粗暴的 [DFS](/search/dfs) : * 注: 为了方便食用, 本文中所有代码省略头文件 * * 注: 为了方便食用, 本文中所有代码省略头文件 ```cpp int n,t; Loading Loading @@ -262,7 +262,6 @@ dp 状态很显然: --- ** 如有疑问或质疑, 请留下评论或私信我 ** ** 如有疑问或质疑, 请留下评论或联系我 GitHub [@interestingLSY](https://github.com/interestingLSY) ** ** questions are welcome ** docs/ds/queue.md +1 −6 Original line number Diff line number Diff line 队列,英文名是 queue,在 C++ STL 中有 [std::queue](https://en.cppreference.com/w/cpp/container/queue) 和 [std::priority_queue](https://en.cppreference.com/w/cpp/container/priority_queue)。 下列说法正确吗? - 先进入队列的元素一定先出队列 - 先进入队列的元素一定后出队列 先进入队列的元素一定先出队列 docs/ds/stack.md +1 −5 Original line number Diff line number Diff line 栈,英文名是 stack, C++ STL 中有 [std::stack](https://en.cppreference.com/w/cpp/container/stack),不过一般都直接用数组模拟一个栈,也十分方便。 下列说法正确吗? - 先进入栈的元素一定先出栈 - 先进入栈的元素一定后出栈 No newline at end of file 先进入栈的元素一定后出栈 Loading
docs/basic/binary.md +2 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ 它每次考察数组当前部分的中间元素,如果中间元素刚好是要找的,就结束搜索过程;如果中间元素小于所查找的值,那么左侧的只会更小,不会有所查找的元素,只需要到右侧去找就好了;如果中间元素大于所查找的值,同理,右侧的只会更大而不会有所查找的元素,所以只需要到左侧去找。 在二分搜索过程中,每次都把查询的区间减半,因此对于一个长度为 $n$ 的数组,至多会进行 $\mathcal {O}(\log n)$ 次查找。 在二分搜索过程中,每次都把查询的区间减半,因此对于一个长度为 $n$ 的数组,至多会进行 $O(\log n)$ 次查找。 ```c++ int binary_search(int start, int end, int key) { Loading
docs/dp/index.md +11 −11 Original line number Diff line number Diff line Loading @@ -127,7 +127,7 @@ $$ ### 最长回文子串 $O(n^2)$:$dp[i] = \max(dp[j] + 1), s(j + 1 .. i)$ 是回文 $O(n^2)$:$dp[i] = \max(dp[j] + 1), s(j + 1 \cdots i)$ 是回文 $O(n)$: Manacher Loading @@ -139,9 +139,9 @@ $p[i]$ 表示从 $i$ 向两侧延伸(当然要保证两侧对应位置相等 这样得到的回文串长度就保证是奇数了 考虑如果按顺序得到了 $p[1 .. i - 1]$,如何计算 $p[i]$ 的值? 考虑如果按顺序得到了 $p[1 \cdots i - 1]$,如何计算 $p[i]$ 的值? 如果之前有一个位置比如说是 $id$,有 $p[id] + id > i$ 那么 $i$ 这个位置是被覆盖了的,根据 $id$ 处的对称性,我们找 $p[id * 2 - i]$ 延伸的部分被 $p[id]$ 延伸的部分所覆盖的那段,显然这段对称回去之后是可以从 $i$ 处延伸出去的长度。 如果之前有一个位置比如说是 $id$,有 $p[id] + id > i$ 那么 $i$ 这个位置是被覆盖了的,根据 $id$ 处的对称性,我们找 $p[id \times 2 - i]$ 延伸的部分被 $p[id]$ 延伸的部分所覆盖的那段,显然这段对称回去之后是可以从 $i$ 处延伸出去的长度。 如果找不到呢?就先让 $p[i] = 1$ 吧。 Loading @@ -167,19 +167,19 @@ upd:其实是[程设期末推荐练习](https://ir1d.cf/2018/06/23/cssx/程设 #### 思路一: $dp[i][j] \ 表示\ 1..i\ 和\ 1..j\ 两条路径$。 $dp[i][j]$ 表示 $1 \cdots i$ 和 $1 \cdots j$ 两条路径。 我们可以人为要求 $1..i$ 是更快的那一条路径。 我们可以人为要求 $1 \cdots i$ 是更快的那一条路径。 这样考虑第 $i$ 个点分给谁。 如果是分给快的那条: $dp[i][j] = \min(dp[i - 1][j] + dis[i - 1][i]),\ j = 1..i$ $dp[i][j] = \min(dp[i - 1][j] + dis[i - 1][i]),\ j = 1 \cdots i$ 如果是慢的,原来是慢的那条就变成了快的,所以另一条是到 $i - 1$ 那个点: $dp[i][j] = \min(dp[i - 1][j] + dis[j][i]),\ j = 1..i$ $dp[i][j] = \min(dp[i - 1][j] + dis[j][i]),\ j = 1 \cdots i$ 答案是 $\min(dp[n][i] + dis[n][i])$。 (从一开始编号,终点是 $n$) Loading @@ -188,9 +188,9 @@ $dp[i][j] = \min(dp[i - 1][j] + dis[j][i]),\ j = 1..i$ #### 思路二 把 $dp[i][j]$ 定义反过来,不是 $1..i$ 和 $1..j$。 把 $dp[i][j]$ 定义反过来,不是 $1 \cdots i$ 和 $1 \cdots j$。 改成是 $i..n$ 和 $j..n$,不要求哪个更快。 改成是 $i..n$ 和 $j \cdots n$,不要求哪个更快。 这样的转移更好写: Loading Loading @@ -269,7 +269,7 @@ ref:https://segmentfault.com/a/1190000008720143 限制:要求相邻两行中删除的像素必须位于同一列或相邻列。 $dp[i][j] = \min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + cost[i][j]$ $dp[i][j] = \min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + cost[i][j]$ 边界:$dp[1][i] = cost[1][i]$。 Loading @@ -279,7 +279,7 @@ $dp[i][j] = \min(dp[i - 1][j], dp[i - 1][j - 1], dp[i - 1][j + 1]) + cost[i][j 等价于之前那个最优二叉搜索树。 $dp[i][j] = \min(dp[i][k] + dp[k][j]) + l[j] - l[i] + 1,\ k = i + 1\ ..\ j - 1$ $dp[i][j] = \min(dp[i][k] + dp[k][j]) + l[j] - l[i] + 1,\ k = i + 1 \cdots j - 1$ 注意 $l[i]$ 表示的是第i个切分点的位置。 Loading
docs/dp/memo.md +3 −4 Original line number Diff line number Diff line Loading @@ -8,9 +8,9 @@ by $\color{Gray}{InterestingLSY}$ (菜到发灰) ## 1. 记忆化搜索是啥 好,就以 [这道题](https://www.luogu.org/problemnew/show/P1048) 为例,我不会动态规划,只会搜索,我就会直接写一个粗暴的 [DFS](/search/dfs) : 好,就以 [洛谷 P1048 采药](https://www.luogu.org/problemnew/show/P1048) 为例,我不会动态规划,只会搜索,我就会直接写一个粗暴的 [DFS](/search/dfs) : * 注: 为了方便食用, 本文中所有代码省略头文件 * * 注: 为了方便食用, 本文中所有代码省略头文件 ```cpp int n,t; Loading Loading @@ -262,7 +262,6 @@ dp 状态很显然: --- ** 如有疑问或质疑, 请留下评论或私信我 ** ** 如有疑问或质疑, 请留下评论或联系我 GitHub [@interestingLSY](https://github.com/interestingLSY) ** ** questions are welcome **
docs/ds/queue.md +1 −6 Original line number Diff line number Diff line 队列,英文名是 queue,在 C++ STL 中有 [std::queue](https://en.cppreference.com/w/cpp/container/queue) 和 [std::priority_queue](https://en.cppreference.com/w/cpp/container/priority_queue)。 下列说法正确吗? - 先进入队列的元素一定先出队列 - 先进入队列的元素一定后出队列 先进入队列的元素一定先出队列
docs/ds/stack.md +1 −5 Original line number Diff line number Diff line 栈,英文名是 stack, C++ STL 中有 [std::stack](https://en.cppreference.com/w/cpp/container/stack),不过一般都直接用数组模拟一个栈,也十分方便。 下列说法正确吗? - 先进入栈的元素一定先出栈 - 先进入栈的元素一定后出栈 No newline at end of file 先进入栈的元素一定后出栈