main
黄海 1 year ago
parent e5ac146784
commit 1e26fc459b

@ -19,7 +19,7 @@ int res;
void dfs(int u, int ul, int dl) {
if (ul + dl >= res) return; // 伟大的剪枝不剪枝会TLE~,中途发现已经大于等于res的情况就返回
if (u == n) { // 走完全程,收集答案
res = ul + dl; // 因为上面的剪枝把ul+dl>=res的全干掉了能到这里的都是<res的都可以用来更新答案
res = min(res, ul + dl);
return;
}
@ -27,7 +27,9 @@ void dfs(int u, int ul, int dl) {
int k = 0;
// 如果把当前导弹使用上升序列的拦截系统进行拦截,那个选择哪个系统呢?
for (k = 0; k < ul; k++)
if (up[k] <= a[u]) break; // up[0],up[1],up[2],... 这样套拦截系统,其数值来讲,是递减的,因为是因为不能再拦截高度更低的才创建了一套新的拦截系统
if (up[k] <= a[u]) break;
// up[0],up[1],up[2],... 这样套拦截系统,其数值来讲,是递减的
// 这是因为不能再拦截高度更低的才创建了一套新的拦截系统
// 找出放到哪个拦截系统上去结果为k
int t = up[k]; // 尝试在第k套系统进行拦截第u个导弹,那么第u个导弹的高度就是第k套系统的新高度

@ -50,14 +50,14 @@ $1≤n≤50$
导弹拦截高度要么一直上升要么一直下降。
有的导弹拦截系统可以选择上升,有的可以选择下降,不是单纯地问 **所存在的序列可以划分为多少组上升子序列** 的问题
**[狄尔沃斯定理](https://www.cnblogs.com/littlehb/p/15650470.html)**,所以不能用之前的方法解, 本题可以上升可以下降,该定理无效
**[狄尔沃斯定理](https://www.cnblogs.com/littlehb/p/15650470.html)**,所以不能用之前的方法解。
#### 2、思路
使用 **暴搜**
**<font color='red'>从问题的解出发</font>,最终问题的答案是有许多单调上升子序列和许多单调下降子序列,对于每个数,思考分别将该数放到上升序列中还是下降序列中,不断走二叉树的不同分支**
**<font color='red'>从问题的解出发</font>,最终问题的答案是有许多单调上升子序列和许多单调下降子序列,对于每个数,思考分别将该数放到上升序列中还是下降序列中,不断走二叉树的不同分支**
#### 3、题解
@ -67,13 +67,12 @@ $up[]$ 存储当前**所有上升子序列的末尾元素**
$down[]$ 存储当前**所有下降子序列的末尾元素**
**$Q$:如何进行搜**
**$Q$:如何进行搜索?**
假设现在要把一个数放入一个上升序列,那么一定是所有能放入的上升序列中,**最后一个元素最大的那一个**。
假设现在要把一个数放入一个上升序列,那么一定是 **所有能放入的上升序列中,最后一个元素最大的那一个**。
**理由**:既然每个数字都要放到一个序列中,对于上升序列,肯定是目前越小越有用,既然能放入大的里面,何必浪费一个小的呢。
**注意**:$up[i]$按这种策略已经是排好序的了,所以只用找最先碰到的一个就行了
> **理由**:既然每个数字都要放到一个序列中,对于上升序列,肯定是目前越小越有用,既然能放入大的里面,何必浪费一个小的呢。
> **注意**:$up[i]$按这种策略已经是排好序的了,所以只用找最先碰到的一个就行了
### 三、$dfs$实现代码
时间$O(n*2^n)$ 空间$O(n)$

Loading…
Cancel
Save