From 0f1816c10ad3b4b5ced3ea6badc90be9452b3e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B5=B7?= <10402852@qq.com> Date: Mon, 4 Mar 2024 13:55:59 +0800 Subject: [PATCH] 'commit' --- TangDou/AcWing_TiGao/T1/LIS/1010.md | 21 ++--------- .../T1/LIS/{1010.cpp => 1010_Dilworth.cpp} | 0 TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp | 37 +++++++++++++++++++ TangDou/AcWing_TiGao/T1/LIS/1016.md | 3 ++ 4 files changed, 44 insertions(+), 17 deletions(-) rename TangDou/AcWing_TiGao/T1/LIS/{1010.cpp => 1010_Dilworth.cpp} (100%) create mode 100644 TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1010.md b/TangDou/AcWing_TiGao/T1/LIS/1010.md index bf6ad2e..9d8e3d7 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/1010.md +++ b/TangDou/AcWing_TiGao/T1/LIS/1010.md @@ -55,26 +55,13 @@ 问题一 套用 $LIS$ 模型即可求解。由 $Dilworth$ 定理,问题二等价于 另一个 $LIS$ 长度 #### 贪心法 -对于每个数,既可以把它接到已有子序列后面,也可以建立一个新序列。要使子序列数最少,应尽量不建立新序列。此外,应让每个子序列的末尾尽可能大,这样能接的数更多。因为一个数若能接到小数后面,必然能接到大数后面,反之则不成立。根据这些想法,可总结出如下贪心流程: +![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202403041334201.png) ->从前往后扫描每个数,对于当前数 -> - 若现有子序列的结尾都小于它,则创建新子序列 -> - 否则,将它放到结尾大于等于它的最小数后面 +我们用两个贪心的证明方法来证明: +![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202403041346994.png) -##### 证明 (最优解 = 贪心解) +![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/202403041346474.png) -假设存在一个最优解,他在考虑第 $i$ 个数放入的下降子序列组中,选择了贪心解方案的后面的一个位置 - -具体如图所示:(绿色部分,更新了$q[i+1]$后为保证递增顺序,交换了$q[i]$和$q[i+1]$,这一步省略了) -![](https://cdn.acwing.com/media/article/image/2021/06/03/55909_ffc9a769c4-IMG_43104A5A0544-1.jpeg) - -可以观察到,该最优策略使得当前局面差于贪心策略,即能接在$(q[i],q[i+1])$范围的子序列少了一个,即 **贪心解** ≤ **最优解** - -同理可证,**最优策略** 在考虑第 $i$ 个数放入的下降子序列组中,选择了贪心解方案的后面的第 $k$ 个位置 也有结论 **贪心解** ≤ **最优解** - -此外,由于**贪心解** 是 **合法解**,所以必然 **贪心解** ≥ **最优解** - -于是有 **贪心解** = **最优解** #### $Code$ 朴素作法 $O(N^2)$ diff --git a/TangDou/AcWing_TiGao/T1/LIS/1010.cpp b/TangDou/AcWing_TiGao/T1/LIS/1010_Dilworth.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1010.cpp rename to TangDou/AcWing_TiGao/T1/LIS/1010_Dilworth.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp b/TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp new file mode 100644 index 0000000..4f0afac --- /dev/null +++ b/TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp @@ -0,0 +1,37 @@ +#include +#include +#include + +using namespace std; + +const int N = 1010; + +int n; +int h[N], f[N], q[N]; + +int main() { + string line; + getline(cin, line); + stringstream ssin(line); + while (ssin >> h[n]) n++; + + int res = 0, cnt = 0; + for (int i = 0; i < n; i++) { + f[i] = 1; + for (int j = 0; j < i; j++) + if (h[i] <= h[j]) + f[i] = max(f[i], f[j] + 1); + res = max(res, f[i]); + + int k = 0; + while (k < cnt && q[k] < h[i]) k++; + if (k == cnt) + q[cnt++] = h[i]; + else + q[k] = h[i]; + } + + printf("%d\n", res); + printf("%d\n", cnt); + return 0; +} \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T1/LIS/1016.md b/TangDou/AcWing_TiGao/T1/LIS/1016.md index ffc0a03..6499db0 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/1016.md +++ b/TangDou/AcWing_TiGao/T1/LIS/1016.md @@ -86,3 +86,6 @@ int main() { **[题解传送门](https://www.cnblogs.com/littlehb/p/17510484.html)** +### 五、关键字 +- 魔改$LIS$ +- 最大上升子序列和 \ No newline at end of file