diff --git a/TangDou/AcWing/BeiBao/10.md b/TangDou/AcWing/Bag/10.md similarity index 100% rename from TangDou/AcWing/BeiBao/10.md rename to TangDou/AcWing/Bag/10.md diff --git a/TangDou/AcWing/BeiBao/1013.md b/TangDou/AcWing/Bag/1013.md similarity index 100% rename from TangDou/AcWing/BeiBao/1013.md rename to TangDou/AcWing/Bag/1013.md diff --git a/TangDou/AcWing/BeiBao/1013_ErWei.cpp b/TangDou/AcWing/Bag/1013_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1013_ErWei.cpp rename to TangDou/AcWing/Bag/1013_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/1013_ShortPath.cpp b/TangDou/AcWing/Bag/1013_ShortPath.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1013_ShortPath.cpp rename to TangDou/AcWing/Bag/1013_ShortPath.cpp diff --git a/TangDou/AcWing/BeiBao/1013_YiWei.cpp b/TangDou/AcWing/Bag/1013_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1013_YiWei.cpp rename to TangDou/AcWing/Bag/1013_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/1019.cpp b/TangDou/AcWing/Bag/1019.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1019.cpp rename to TangDou/AcWing/Bag/1019.cpp diff --git a/TangDou/AcWing/BeiBao/1019.md b/TangDou/AcWing/Bag/1019.md similarity index 100% rename from TangDou/AcWing/BeiBao/1019.md rename to TangDou/AcWing/Bag/1019.md diff --git a/TangDou/AcWing/BeiBao/1020.md b/TangDou/AcWing/Bag/1020.md similarity index 100% rename from TangDou/AcWing/BeiBao/1020.md rename to TangDou/AcWing/Bag/1020.md diff --git a/TangDou/AcWing/BeiBao/1020_1.cpp b/TangDou/AcWing/Bag/1020_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1020_1.cpp rename to TangDou/AcWing/Bag/1020_1.cpp diff --git a/TangDou/AcWing/BeiBao/1020_2.cpp b/TangDou/AcWing/Bag/1020_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1020_2.cpp rename to TangDou/AcWing/Bag/1020_2.cpp diff --git a/TangDou/AcWing/BeiBao/1021.cpp b/TangDou/AcWing/Bag/1021.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1021.cpp rename to TangDou/AcWing/Bag/1021.cpp diff --git a/TangDou/AcWing/BeiBao/1021.drawio b/TangDou/AcWing/Bag/1021.drawio similarity index 100% rename from TangDou/AcWing/BeiBao/1021.drawio rename to TangDou/AcWing/Bag/1021.drawio diff --git a/TangDou/AcWing/BeiBao/1021.md b/TangDou/AcWing/Bag/1021.md similarity index 100% rename from TangDou/AcWing/BeiBao/1021.md rename to TangDou/AcWing/Bag/1021.md diff --git a/TangDou/AcWing/BeiBao/1022.cpp b/TangDou/AcWing/Bag/1022.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1022.cpp rename to TangDou/AcWing/Bag/1022.cpp diff --git a/TangDou/AcWing/BeiBao/1022.md b/TangDou/AcWing/Bag/1022.md similarity index 100% rename from TangDou/AcWing/BeiBao/1022.md rename to TangDou/AcWing/Bag/1022.md diff --git a/TangDou/AcWing/BeiBao/1022_LianXiTi.cpp b/TangDou/AcWing/Bag/1022_LianXiTi.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1022_LianXiTi.cpp rename to TangDou/AcWing/Bag/1022_LianXiTi.cpp diff --git a/TangDou/AcWing/BeiBao/1023.md b/TangDou/AcWing/Bag/1023.md similarity index 100% rename from TangDou/AcWing/BeiBao/1023.md rename to TangDou/AcWing/Bag/1023.md diff --git a/TangDou/AcWing/BeiBao/1023_0.cpp b/TangDou/AcWing/Bag/1023_0.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1023_0.cpp rename to TangDou/AcWing/Bag/1023_0.cpp diff --git a/TangDou/AcWing/BeiBao/1023_1.cpp b/TangDou/AcWing/Bag/1023_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1023_1.cpp rename to TangDou/AcWing/Bag/1023_1.cpp diff --git a/TangDou/AcWing/BeiBao/1023_2.cpp b/TangDou/AcWing/Bag/1023_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1023_2.cpp rename to TangDou/AcWing/Bag/1023_2.cpp diff --git a/TangDou/AcWing/BeiBao/1024.md b/TangDou/AcWing/Bag/1024.md similarity index 100% rename from TangDou/AcWing/BeiBao/1024.md rename to TangDou/AcWing/Bag/1024.md diff --git a/TangDou/AcWing/BeiBao/1024_1.cpp b/TangDou/AcWing/Bag/1024_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1024_1.cpp rename to TangDou/AcWing/Bag/1024_1.cpp diff --git a/TangDou/AcWing/BeiBao/1024_2.cpp b/TangDou/AcWing/Bag/1024_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/1024_2.cpp rename to TangDou/AcWing/Bag/1024_2.cpp diff --git a/TangDou/AcWing/BeiBao/10_DfsOrder.cpp b/TangDou/AcWing/Bag/10_DfsOrder.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/10_DfsOrder.cpp rename to TangDou/AcWing/Bag/10_DfsOrder.cpp diff --git a/TangDou/AcWing/BeiBao/10_DuoChaShu_To_ErChaShu.cpp b/TangDou/AcWing/Bag/10_DuoChaShu_To_ErChaShu.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/10_DuoChaShu_To_ErChaShu.cpp rename to TangDou/AcWing/Bag/10_DuoChaShu_To_ErChaShu.cpp diff --git a/TangDou/AcWing/BeiBao/10_ErWei.cpp b/TangDou/AcWing/Bag/10_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/10_ErWei.cpp rename to TangDou/AcWing/Bag/10_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/10_SanWei.cpp b/TangDou/AcWing/Bag/10_SanWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/10_SanWei.cpp rename to TangDou/AcWing/Bag/10_SanWei.cpp diff --git a/TangDou/AcWing/BeiBao/11.md b/TangDou/AcWing/Bag/11.md similarity index 100% rename from TangDou/AcWing/BeiBao/11.md rename to TangDou/AcWing/Bag/11.md diff --git a/TangDou/AcWing/BeiBao/11_ErWei_1.cpp b/TangDou/AcWing/Bag/11_ErWei_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/11_ErWei_1.cpp rename to TangDou/AcWing/Bag/11_ErWei_1.cpp diff --git a/TangDou/AcWing/BeiBao/11_ErWei_2.cpp b/TangDou/AcWing/Bag/11_ErWei_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/11_ErWei_2.cpp rename to TangDou/AcWing/Bag/11_ErWei_2.cpp diff --git a/TangDou/AcWing/BeiBao/11_YiWei_1.cpp b/TangDou/AcWing/Bag/11_YiWei_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/11_YiWei_1.cpp rename to TangDou/AcWing/Bag/11_YiWei_1.cpp diff --git a/TangDou/AcWing/BeiBao/11_YiWei_2.cpp b/TangDou/AcWing/Bag/11_YiWei_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/11_YiWei_2.cpp rename to TangDou/AcWing/Bag/11_YiWei_2.cpp diff --git a/TangDou/AcWing/BeiBao/12.cpp b/TangDou/AcWing/Bag/12.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/12.cpp rename to TangDou/AcWing/Bag/12.cpp diff --git a/TangDou/AcWing/BeiBao/12.md b/TangDou/AcWing/Bag/12.md similarity index 100% rename from TangDou/AcWing/BeiBao/12.md rename to TangDou/AcWing/Bag/12.md diff --git a/TangDou/AcWing/BeiBao/2.md b/TangDou/AcWing/Bag/2.md similarity index 100% rename from TangDou/AcWing/BeiBao/2.md rename to TangDou/AcWing/Bag/2.md diff --git a/TangDou/AcWing/BeiBao/278.md b/TangDou/AcWing/Bag/278.md similarity index 95% rename from TangDou/AcWing/BeiBao/278.md rename to TangDou/AcWing/Bag/278.md index 36e5153..719b1e8 100644 --- a/TangDou/AcWing/BeiBao/278.md +++ b/TangDou/AcWing/Bag/278.md @@ -131,7 +131,7 @@ int main() { $A:$我们可以将结论推广到不同属性的情况下,本题的属性是数量,但如果是最大价值呢? 我们不难得到需要将$f[0]$初始化为$0$,$f[1\sim n]$初始化为负无穷 -为什么要这样设置呢?因为每一个新状态,都需要知道它可以从哪些旧状态转移而来,如果上一个状态是合法的,那么有可能从上一个状态转移而来,但如何标识上一个状态是不是合法呢?比如如果初始化状态值是$0$,并且上一个状态是$0$,表示的是目前的最大值,那是不是合法呢?不好说啊,为什么呢? +为什么要这样设置呢?因为每一个新状态,都需要知道它可以从哪些旧状态转移而来,如果上一个状态是合法的,那么有可能从上一个状态转移而来,但如何标识上一个状态是不是合法呢?比如如果初始化状态值是$0$,并且上一个状态是$0$,表示的是目前的最大值,那要是不合法呢?不好说啊,为什么呢? * 上一个状态不合法,没有状态转移过来 * 上一个状态合法,因为有负数等原因,造成最大值确实为$0$ diff --git a/TangDou/AcWing/BeiBao/278_1.cpp b/TangDou/AcWing/Bag/278_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/278_1.cpp rename to TangDou/AcWing/Bag/278_1.cpp diff --git a/TangDou/AcWing/BeiBao/278_2.cpp b/TangDou/AcWing/Bag/278_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/278_2.cpp rename to TangDou/AcWing/Bag/278_2.cpp diff --git a/TangDou/AcWing/BeiBao/2_ErWei.cpp b/TangDou/AcWing/Bag/2_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_ErWei.cpp rename to TangDou/AcWing/Bag/2_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/2_QiaHaoFill.in b/TangDou/AcWing/Bag/2_QiaHaoFill.in similarity index 100% rename from TangDou/AcWing/BeiBao/2_QiaHaoFill.in rename to TangDou/AcWing/Bag/2_QiaHaoFill.in diff --git a/TangDou/AcWing/BeiBao/2_QiaHaoFill_ErWei.cpp b/TangDou/AcWing/Bag/2_QiaHaoFill_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_QiaHaoFill_ErWei.cpp rename to TangDou/AcWing/Bag/2_QiaHaoFill_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/2_QiaHaoFill_YiWei.cpp b/TangDou/AcWing/Bag/2_QiaHaoFill_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_QiaHaoFill_YiWei.cpp rename to TangDou/AcWing/Bag/2_QiaHaoFill_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/2_YiWei.cpp b/TangDou/AcWing/Bag/2_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_YiWei.cpp rename to TangDou/AcWing/Bag/2_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/2_dfs_int.cpp b/TangDou/AcWing/Bag/2_dfs_int.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_dfs_int.cpp rename to TangDou/AcWing/Bag/2_dfs_int.cpp diff --git a/TangDou/AcWing/BeiBao/2_dfs_int_jiyihua.cpp b/TangDou/AcWing/Bag/2_dfs_int_jiyihua.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_dfs_int_jiyihua.cpp rename to TangDou/AcWing/Bag/2_dfs_int_jiyihua.cpp diff --git a/TangDou/AcWing/BeiBao/2_dfs_void.cpp b/TangDou/AcWing/Bag/2_dfs_void.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/2_dfs_void.cpp rename to TangDou/AcWing/Bag/2_dfs_void.cpp diff --git a/TangDou/AcWing/BeiBao/3.md b/TangDou/AcWing/Bag/3.md similarity index 100% rename from TangDou/AcWing/BeiBao/3.md rename to TangDou/AcWing/Bag/3.md diff --git a/TangDou/AcWing/BeiBao/3_0.cpp b/TangDou/AcWing/Bag/3_0.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/3_0.cpp rename to TangDou/AcWing/Bag/3_0.cpp diff --git a/TangDou/AcWing/BeiBao/3_ErWei.cpp b/TangDou/AcWing/Bag/3_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/3_ErWei.cpp rename to TangDou/AcWing/Bag/3_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/3_YiWei.cpp b/TangDou/AcWing/Bag/3_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/3_YiWei.cpp rename to TangDou/AcWing/Bag/3_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/4.md b/TangDou/AcWing/Bag/4.md similarity index 100% rename from TangDou/AcWing/BeiBao/4.md rename to TangDou/AcWing/Bag/4.md diff --git a/TangDou/AcWing/BeiBao/423.md b/TangDou/AcWing/Bag/423.md similarity index 88% rename from TangDou/AcWing/BeiBao/423.md rename to TangDou/AcWing/Bag/423.md index 4297128..9f70945 100644 --- a/TangDou/AcWing/BeiBao/423.md +++ b/TangDou/AcWing/Bag/423.md @@ -37,13 +37,16 @@ $1≤T≤1000$,$1≤M≤100$ ### 二、题目解析 -注意一下$m$和$n$的录入顺序。 **01背包模型** -**状态表示$f(i,j)$—集合**: 考虑前 $i$ 个物品,且当前已使用体积为$ j$ 的方案 +**状态表示** -**状态表示$f(i,j)$—属性**: 该方案的价值为最大值 $max$ +$f(i,j)$ +- **集合** +考虑前 $i$ 个物品,且当前已使用体积为$ j$ 的方案 +- **属性** +该方案的价值为最大值 $max$ **状态转移$f(i,j)$**: @@ -65,7 +68,6 @@ $$f(i,j)=\begin{equation} ### 三、二维朴素作法 -空间复杂度:$O(n×m)$ 时间复杂度:$O(n×m)$ ```cpp {.line-numbers} diff --git a/TangDou/AcWing/BeiBao/423_1.cpp b/TangDou/AcWing/Bag/423_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/423_1.cpp rename to TangDou/AcWing/Bag/423_1.cpp diff --git a/TangDou/AcWing/BeiBao/423_2.cpp b/TangDou/AcWing/Bag/423_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/423_2.cpp rename to TangDou/AcWing/Bag/423_2.cpp diff --git a/TangDou/AcWing/BeiBao/426.cpp b/TangDou/AcWing/Bag/426.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/426.cpp rename to TangDou/AcWing/Bag/426.cpp diff --git a/TangDou/AcWing/BeiBao/426.md b/TangDou/AcWing/Bag/426.md similarity index 100% rename from TangDou/AcWing/BeiBao/426.md rename to TangDou/AcWing/Bag/426.md diff --git a/TangDou/AcWing/BeiBao/487.md b/TangDou/AcWing/Bag/487.md similarity index 100% rename from TangDou/AcWing/BeiBao/487.md rename to TangDou/AcWing/Bag/487.md diff --git a/TangDou/AcWing/BeiBao/487_FZ1.cpp b/TangDou/AcWing/Bag/487_FZ1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/487_FZ1.cpp rename to TangDou/AcWing/Bag/487_FZ1.cpp diff --git a/TangDou/AcWing/BeiBao/487_FZ2.cpp b/TangDou/AcWing/Bag/487_FZ2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/487_FZ2.cpp rename to TangDou/AcWing/Bag/487_FZ2.cpp diff --git a/TangDou/AcWing/BeiBao/487_Prepare.cpp b/TangDou/AcWing/Bag/487_Prepare.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/487_Prepare.cpp rename to TangDou/AcWing/Bag/487_Prepare.cpp diff --git a/TangDou/AcWing/BeiBao/4_ErWei.cpp b/TangDou/AcWing/Bag/4_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/4_ErWei.cpp rename to TangDou/AcWing/Bag/4_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/4_YiWei.cpp b/TangDou/AcWing/Bag/4_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/4_YiWei.cpp rename to TangDou/AcWing/Bag/4_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/5.md b/TangDou/AcWing/Bag/5.md similarity index 100% rename from TangDou/AcWing/BeiBao/5.md rename to TangDou/AcWing/Bag/5.md diff --git a/TangDou/AcWing/BeiBao/532.cpp b/TangDou/AcWing/Bag/532.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/532.cpp rename to TangDou/AcWing/Bag/532.cpp diff --git a/TangDou/AcWing/BeiBao/532.md b/TangDou/AcWing/Bag/532.md similarity index 100% rename from TangDou/AcWing/BeiBao/532.md rename to TangDou/AcWing/Bag/532.md diff --git a/TangDou/AcWing/BeiBao/5_ErWei_GunDong.cpp b/TangDou/AcWing/Bag/5_ErWei_GunDong.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/5_ErWei_GunDong.cpp rename to TangDou/AcWing/Bag/5_ErWei_GunDong.cpp diff --git a/TangDou/AcWing/BeiBao/5_YiWei.cpp b/TangDou/AcWing/Bag/5_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/5_YiWei.cpp rename to TangDou/AcWing/Bag/5_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/6.md b/TangDou/AcWing/Bag/6.md similarity index 100% rename from TangDou/AcWing/BeiBao/6.md rename to TangDou/AcWing/Bag/6.md diff --git a/TangDou/AcWing/BeiBao/6_ErWei.cpp b/TangDou/AcWing/Bag/6_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/6_ErWei.cpp rename to TangDou/AcWing/Bag/6_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/6_YiWei+Copy.cpp b/TangDou/AcWing/Bag/6_YiWei+Copy.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/6_YiWei+Copy.cpp rename to TangDou/AcWing/Bag/6_YiWei+Copy.cpp diff --git a/TangDou/AcWing/BeiBao/7.cpp b/TangDou/AcWing/Bag/7.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/7.cpp rename to TangDou/AcWing/Bag/7.cpp diff --git a/TangDou/AcWing/BeiBao/7.md b/TangDou/AcWing/Bag/7.md similarity index 100% rename from TangDou/AcWing/BeiBao/7.md rename to TangDou/AcWing/Bag/7.md diff --git a/TangDou/AcWing/BeiBao/734.md b/TangDou/AcWing/Bag/734.md similarity index 100% rename from TangDou/AcWing/BeiBao/734.md rename to TangDou/AcWing/Bag/734.md diff --git a/TangDou/AcWing/BeiBao/734_ErWei.cpp b/TangDou/AcWing/Bag/734_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/734_ErWei.cpp rename to TangDou/AcWing/Bag/734_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/734_YiWei.cpp b/TangDou/AcWing/Bag/734_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/734_YiWei.cpp rename to TangDou/AcWing/Bag/734_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/8.md b/TangDou/AcWing/Bag/8.md similarity index 100% rename from TangDou/AcWing/BeiBao/8.md rename to TangDou/AcWing/Bag/8.md diff --git a/TangDou/AcWing/BeiBao/8_1.cpp b/TangDou/AcWing/Bag/8_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/8_1.cpp rename to TangDou/AcWing/Bag/8_1.cpp diff --git a/TangDou/AcWing/BeiBao/8_2.cpp b/TangDou/AcWing/Bag/8_2.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/8_2.cpp rename to TangDou/AcWing/Bag/8_2.cpp diff --git a/TangDou/AcWing/BeiBao/9.md b/TangDou/AcWing/Bag/9.md similarity index 100% rename from TangDou/AcWing/BeiBao/9.md rename to TangDou/AcWing/Bag/9.md diff --git a/TangDou/AcWing/BeiBao/9_ErWei.cpp b/TangDou/AcWing/Bag/9_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/9_ErWei.cpp rename to TangDou/AcWing/Bag/9_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/9_YiWei.cpp b/TangDou/AcWing/Bag/9_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/9_YiWei.cpp rename to TangDou/AcWing/Bag/9_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/DuoChaShuToErChaShu.cpp b/TangDou/AcWing/Bag/DuoChaShuToErChaShu.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/DuoChaShuToErChaShu.cpp rename to TangDou/AcWing/Bag/DuoChaShuToErChaShu.cpp diff --git a/TangDou/AcWing/BeiBao/DuoChaShuToErChaShu.in b/TangDou/AcWing/Bag/DuoChaShuToErChaShu.in similarity index 100% rename from TangDou/AcWing/BeiBao/DuoChaShuToErChaShu.in rename to TangDou/AcWing/Bag/DuoChaShuToErChaShu.in diff --git a/TangDou/AcWing/BeiBao/FangAnShu/P1832_0.cpp b/TangDou/AcWing/Bag/FangAnShu/P1832_0.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/P1832_0.cpp rename to TangDou/AcWing/Bag/FangAnShu/P1832_0.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/P1832_1.cpp b/TangDou/AcWing/Bag/FangAnShu/P1832_1.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/P1832_1.cpp rename to TangDou/AcWing/Bag/FangAnShu/P1832_1.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/QiaHao_01.in b/TangDou/AcWing/Bag/FangAnShu/QiaHao_01.in similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/QiaHao_01.in rename to TangDou/AcWing/Bag/FangAnShu/QiaHao_01.in diff --git a/TangDou/AcWing/BeiBao/FangAnShu/QiaHao_01_ErWei.cpp b/TangDou/AcWing/Bag/FangAnShu/QiaHao_01_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/QiaHao_01_ErWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/QiaHao_01_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/QiaHao_01_YiWei.cpp b/TangDou/AcWing/Bag/FangAnShu/QiaHao_01_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/QiaHao_01_YiWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/QiaHao_01_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/QiaHao_WQ.in b/TangDou/AcWing/Bag/FangAnShu/QiaHao_WQ.in similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/QiaHao_WQ.in rename to TangDou/AcWing/Bag/FangAnShu/QiaHao_WQ.in diff --git a/TangDou/AcWing/BeiBao/FangAnShu/QiaHao_WQ_ErWei.cpp b/TangDou/AcWing/Bag/FangAnShu/QiaHao_WQ_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/QiaHao_WQ_ErWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/QiaHao_WQ_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/QiaHao_WQ_YiWei.cpp b/TangDou/AcWing/Bag/FangAnShu/QiaHao_WQ_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/QiaHao_WQ_YiWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/QiaHao_WQ_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_01.in b/TangDou/AcWing/Bag/FangAnShu/ZhiDuo_01.in similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_01.in rename to TangDou/AcWing/Bag/FangAnShu/ZhiDuo_01.in diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_01_ErWei.cpp b/TangDou/AcWing/Bag/FangAnShu/ZhiDuo_01_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_01_ErWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/ZhiDuo_01_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_01_YiWei.cpp b/TangDou/AcWing/Bag/FangAnShu/ZhiDuo_01_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_01_YiWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/ZhiDuo_01_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_WQ.in b/TangDou/AcWing/Bag/FangAnShu/ZhiDuo_WQ.in similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_WQ.in rename to TangDou/AcWing/Bag/FangAnShu/ZhiDuo_WQ.in diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_WQ_ErWei.cpp b/TangDou/AcWing/Bag/FangAnShu/ZhiDuo_WQ_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_WQ_ErWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/ZhiDuo_WQ_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_WQ_YiWei.cpp b/TangDou/AcWing/Bag/FangAnShu/ZhiDuo_WQ_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiDuo_WQ_YiWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/ZhiDuo_WQ_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiShao_01_ErWei.cpp b/TangDou/AcWing/Bag/FangAnShu/ZhiShao_01_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiShao_01_ErWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/ZhiShao_01_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/FangAnShu/ZhiShao_01_YiWei.cpp b/TangDou/AcWing/Bag/FangAnShu/ZhiShao_01_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/FangAnShu/ZhiShao_01_YiWei.cpp rename to TangDou/AcWing/Bag/FangAnShu/ZhiShao_01_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Max.in b/TangDou/AcWing/Bag/MaxMin/QiaHao_01_Max.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Max.in rename to TangDou/AcWing/Bag/MaxMin/QiaHao_01_Max.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Max_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_01_Max_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Max_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_01_Max_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Max_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_01_Max_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Max_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_01_Max_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Min.in b/TangDou/AcWing/Bag/MaxMin/QiaHao_01_Min.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Min.in rename to TangDou/AcWing/Bag/MaxMin/QiaHao_01_Min.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Min_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_01_Min_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Min_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_01_Min_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Min_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_01_Min_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_01_Min_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_01_Min_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Max.in b/TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Max.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Max.in rename to TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Max.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Max_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Max_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Max_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Max_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Max_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Max_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Max_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Max_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Min.in b/TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Min.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Min.in rename to TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Min.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Min_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Min_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Min_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Min_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Min_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Min_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/QiaHao_WQ_Min_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/QiaHao_WQ_Min_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_01.in b/TangDou/AcWing/Bag/MaxMin/ZhiDuo_01.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_01.in rename to TangDou/AcWing/Bag/MaxMin/ZhiDuo_01.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_01_Max_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiDuo_01_Max_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_01_Max_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiDuo_01_Max_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_01_Max_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiDuo_01_Max_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_01_Max_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiDuo_01_Max_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_WQ.in b/TangDou/AcWing/Bag/MaxMin/ZhiDuo_WQ.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_WQ.in rename to TangDou/AcWing/Bag/MaxMin/ZhiDuo_WQ.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_WQ_Max_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiDuo_WQ_Max_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_WQ_Max_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiDuo_WQ_Max_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_WQ_Max_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiDuo_WQ_Max_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiDuo_WQ_Max_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiDuo_WQ_Max_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiShao_01_Min.in b/TangDou/AcWing/Bag/MaxMin/ZhiShao_01_Min.in similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiShao_01_Min.in rename to TangDou/AcWing/Bag/MaxMin/ZhiShao_01_Min.in diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiShao_01_Min_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiShao_01_Min_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiShao_01_Min_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiShao_01_Min_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiShao_01_Min_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiShao_01_Min_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiShao_01_Min_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiShao_01_Min_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiShao_WQ_Min_ErWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiShao_WQ_Min_ErWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiShao_WQ_Min_ErWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiShao_WQ_Min_ErWei.cpp diff --git a/TangDou/AcWing/BeiBao/MaxMin/ZhiShao_WQ_Min_YiWei.cpp b/TangDou/AcWing/Bag/MaxMin/ZhiShao_WQ_Min_YiWei.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/MaxMin/ZhiShao_WQ_Min_YiWei.cpp rename to TangDou/AcWing/Bag/MaxMin/ZhiShao_WQ_Min_YiWei.cpp diff --git a/TangDou/AcWing/BeiBao/Test.cpp b/TangDou/AcWing/Bag/Test.cpp similarity index 100% rename from TangDou/AcWing/BeiBao/Test.cpp rename to TangDou/AcWing/Bag/Test.cpp diff --git a/TangDou/AcWing/BeiBao/【总结】01背包与完全背包专题.md b/TangDou/AcWing/Bag/【总结】01背包与完全背包专题.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】01背包与完全背包专题.md rename to TangDou/AcWing/Bag/【总结】01背包与完全背包专题.md diff --git a/TangDou/AcWing/BeiBao/【总结】动态规划的具体路径输出.md b/TangDou/AcWing/Bag/【总结】动态规划的具体路径输出.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】动态规划的具体路径输出.md rename to TangDou/AcWing/Bag/【总结】动态规划的具体路径输出.md diff --git a/TangDou/AcWing/BeiBao/【总结】多叉树转二叉树-有依赖的背包问题解法.md b/TangDou/AcWing/Bag/【总结】多叉树转二叉树-有依赖的背包问题解法.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】多叉树转二叉树-有依赖的背包问题解法.md rename to TangDou/AcWing/Bag/【总结】多叉树转二叉树-有依赖的背包问题解法.md diff --git a/TangDou/AcWing/BeiBao/【总结】多叉树转二叉树.md b/TangDou/AcWing/Bag/【总结】多叉树转二叉树.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】多叉树转二叉树.md rename to TangDou/AcWing/Bag/【总结】多叉树转二叉树.md diff --git a/TangDou/AcWing/BeiBao/【总结】方案数-空间恰好j.md b/TangDou/AcWing/Bag/【总结】方案数-空间恰好j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】方案数-空间恰好j.md rename to TangDou/AcWing/Bag/【总结】方案数-空间恰好j.md diff --git a/TangDou/AcWing/BeiBao/【总结】方案数-空间至多j.md b/TangDou/AcWing/Bag/【总结】方案数-空间至多j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】方案数-空间至多j.md rename to TangDou/AcWing/Bag/【总结】方案数-空间至多j.md diff --git a/TangDou/AcWing/BeiBao/【总结】方案数-空间至少j.md b/TangDou/AcWing/Bag/【总结】方案数-空间至少j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】方案数-空间至少j.md rename to TangDou/AcWing/Bag/【总结】方案数-空间至少j.md diff --git a/TangDou/AcWing/BeiBao/【总结】最大价值-空间恰好是j.md b/TangDou/AcWing/Bag/【总结】最大价值-空间恰好是j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】最大价值-空间恰好是j.md rename to TangDou/AcWing/Bag/【总结】最大价值-空间恰好是j.md diff --git a/TangDou/AcWing/BeiBao/【总结】最大价值-空间至多j.md b/TangDou/AcWing/Bag/【总结】最大价值-空间至多j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】最大价值-空间至多j.md rename to TangDou/AcWing/Bag/【总结】最大价值-空间至多j.md diff --git a/TangDou/AcWing/BeiBao/【总结】最小价值-空间恰好j.md b/TangDou/AcWing/Bag/【总结】最小价值-空间恰好j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】最小价值-空间恰好j.md rename to TangDou/AcWing/Bag/【总结】最小价值-空间恰好j.md diff --git a/TangDou/AcWing/BeiBao/【总结】最小价值-空间至少是j.md b/TangDou/AcWing/Bag/【总结】最小价值-空间至少是j.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】最小价值-空间至少是j.md rename to TangDou/AcWing/Bag/【总结】最小价值-空间至少是j.md diff --git a/TangDou/AcWing/BeiBao/【总结】背包问题的至多_恰好_至少-主帖.md b/TangDou/AcWing/Bag/【总结】背包问题的至多_恰好_至少-主帖.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】背包问题的至多_恰好_至少-主帖.md rename to TangDou/AcWing/Bag/【总结】背包问题的至多_恰好_至少-主帖.md diff --git a/TangDou/AcWing/BeiBao/【总结】脑图形式(一维)总结.md b/TangDou/AcWing/Bag/【总结】脑图形式(一维)总结.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】脑图形式(一维)总结.md rename to TangDou/AcWing/Bag/【总结】脑图形式(一维)总结.md diff --git a/TangDou/AcWing/BeiBao/【总结】脑图形式(二维)总结.md b/TangDou/AcWing/Bag/【总结】脑图形式(二维)总结.md similarity index 100% rename from TangDou/AcWing/BeiBao/【总结】脑图形式(二维)总结.md rename to TangDou/AcWing/Bag/【总结】脑图形式(二维)总结.md diff --git a/TangDou/AcWing/Bag/背包问题专题,md b/TangDou/AcWing/Bag/背包问题专题,md new file mode 100644 index 0000000..2e193bd --- /dev/null +++ b/TangDou/AcWing/Bag/背包问题专题,md @@ -0,0 +1,174 @@ +## 背包问题 + +### 一、$01$背包基础题 +**[$AcWing$ $2$. $01$背包问题](https://www.acwing.com/problem/content/2/)** + +**[$AcWing$ $423$. 采药](https://www.acwing.com/problem/content/425/)** + +**[$AcWing$ $1024$. 装箱问题](https://www.acwing.com/problem/content/1026/)** + +二维状态表示 +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 110; +const int M = 1010; + +int n, m; +int w[N], v[N]; +int f[N][M]; + +int main() { + cin >> m >> n; + + for (int i = 1; i <= n; i++) cin >> v[i] >> w[i]; + + for (int i = 1; i <= n; i++) + for (int j = 1; j <= m; j++) { + f[i][j] = f[i - 1][j]; // 不选 + if (j >= v[i]) + f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); // 选 + } + printf("%d\n", f[n][m]); + return 0; +} + +``` + +一维状态表示 +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 1010; + +int n, m; +int v[N], w[N]; +int f[N]; + +int main() { + cin >> m >> n; + for (int i = 1; i <= n; i++) cin >> v[i] >> w[i]; + + // 01背包模板 + for (int i = 1; i <= n; i++) + for (int j = m; j >= v[i]; j--) + f[j] = max(f[j], f[j - v[i]] + w[i]); + + printf("%d\n", f[m]); + return 0; +} +``` + + +### 二、二维费用$01$背包问题 +**[$AcWing$ $1022$. 宠物小精灵之收服](https://www.acwing.com/problem/content/1024/)** + +**[$AcWing$ $8$. 二维费用的背包问题](https://www.cnblogs.com/littlehb/p/15684961.html)** + +```cpp {.line-numbers} +#include + +using namespace std; + +const int N = 110; // 野生小精灵的数量 +const int M1 = 1010; // 小智的精灵球数量 +const int M2 = 510; // 皮卡丘的体力值 + +int n, m1, m2; +int f[M1][M2]; // 一维:精灵球数量,二维:皮卡丘的体力值,值:抓到的小精灵数量最大值 + +int main() { + cin >> m1 >> m2 >> n; + m2--; // 留一滴血 + + // 二维费用01背包 + // 降维需要将体积1、体积2倒序枚举 + for (int i = 1; i <= n; i++) { + int v1, v2; + cin >> v1 >> v2; + for (int j = m1; j >= v1; j--) + for (int k = m2; k >= v2; k--) + f[j][k] = max(f[j][k], f[j - v1][k - v2] + 1); // 获利就是多了一个小精灵 + } + // 最多收服多少个小精灵[在消耗精灵球、血极限的情况下,肯定抓的是最多的,这不废话吗] + printf("%d ", f[m1][m2]); + + // 找到满足最大价值的所有状态里,第二维费用消耗最少的 + int cost = m2; + for (int i = 0; i <= m2; i++) // 如果一个都不收服,则体力消耗最少,消耗值为0 + if (f[m1][i] == f[m1][m2]) + cost = min(cost, i); + + // 收服最多个小精灵时皮卡丘的剩余体力值最大是多少 + printf("%d\n", m2 + 1 - cost); + return 0; +} +``` + +**总结** +- $01$背包,还是背一维的形式比较好,一来代码更短,二来空间更省,倒序就完了。 +- 二维费用的$01$背包,简化版本的$01$背包模板就有了用武之地,因为三维数组可能会爆内存。 + +### 三、$01$背包之恰好装满 +**[$AcWing$ $278$. 数字组合](https://www.acwing.com/problem/content/280/)** + +**二维代码** +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 110; +const int M = 10010; +int n, m; +int v; +int f[N][M]; + +int main() { + cin >> n >> m; + + for (int i = 0; i <= n; i++) f[i][0] = 1; // base case + + for (int i = 1; i <= n; i++) { + cin >> v; + for (int j = 1; j <= m; j++) { + // 从前i-1个物品中选择,装满j这么大的空间,假设方案数是5个 + // 那么,在前i个物品中选择,装满j这么大的空间,方案数最少也是5个 + // 如果第i个物品,可以选择,那么可能使得最终的选择方案数增加 + f[i][j] = f[i - 1][j]; + // 增加多少呢?前序依赖是:f[i - 1][j - v] + if (j >= v) f[i][j] += f[i - 1][j - v]; + } + } + // 输出结果 + printf("%d\n", f[n][m]); + return 0; +} +``` + +**一维代码** +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 10010; + +int n, m; +int v; +int f[N]; // 在前i个物品,体积是j的情况下,恰好装满的方案数 + +int main() { + cin >> n >> m; + + // 体积恰好j, f[0]=1, 其余是0 + f[0] = 1; + for (int i = 1; i <= n; i++) { + cin >> v; + for (int j = m; j >= v; j--) + f[j] += f[j - v]; + } + printf("%d\n", f[m]); + return 0; +} +``` diff --git a/TangDou/AcWing_TiGao/T1/LIS/1010.md b/TangDou/AcWing/LIS/1010.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1010.md rename to TangDou/AcWing/LIS/1010.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/1010_Dilworth.cpp b/TangDou/AcWing/LIS/1010_Dilworth.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1010_Dilworth.cpp rename to TangDou/AcWing/LIS/1010_Dilworth.cpp diff --git a/TangDou/AcWing/LIS/1010_TanXin.cpp b/TangDou/AcWing/LIS/1010_TanXin.cpp new file mode 100644 index 0000000..0dbfd95 --- /dev/null +++ b/TangDou/AcWing/LIS/1010_TanXin.cpp @@ -0,0 +1,31 @@ +#include +using namespace std; + +const int N = 1010; + +int a[N], f[N]; // 每个导弹的高度,f[i]:以a[i]结尾的最长不升子序列长度 +int q[N], ql; // 需要ql套拦截系统,每个拦截系统最后一个拦截高度为q[i] +int n, res; + +int main() { + while (cin >> a[n]) n++; + // 第一问 + for (int i = 0; i < n; i++) { + f[i] = 1; + for (int j = 0; j < i; j++) + if (a[i] <= a[j]) // 如果前面的比当前的大,说明是不升序列 + f[i] = max(f[i], f[j] + 1); + res = max(res, f[i]); + } + // 第二问 + for (int i = 0; i < n; i++) { + int p = lower_bound(q, q + ql, a[i]) - q; + if (p == ql) // 如果没有找到可以接在后面的导弹拦截系统,那么需要创建一套新的拦截系统 + q[ql++] = a[i]; + else + q[p] = a[i]; // 否则就直接接到找到的第k套拦截系统的后面,那么,第k套拦截系统的最后一个拦截高度=q[k]=h[i] + } + // 输出最长不升序列长度,即:最多能拦截的导弹数 + printf("%d\n%d\n", res, ql); + return 0; +} \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T1/LIS/1012.md b/TangDou/AcWing/LIS/1012.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1012.md rename to TangDou/AcWing/LIS/1012.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/1012_1.cpp b/TangDou/AcWing/LIS/1012_1.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1012_1.cpp rename to TangDou/AcWing/LIS/1012_1.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1012_2.cpp b/TangDou/AcWing/LIS/1012_2.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1012_2.cpp rename to TangDou/AcWing/LIS/1012_2.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1014.md b/TangDou/AcWing/LIS/1014.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1014.md rename to TangDou/AcWing/LIS/1014.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/1014_1.cpp b/TangDou/AcWing/LIS/1014_1.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1014_1.cpp rename to TangDou/AcWing/LIS/1014_1.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1014_2.cpp b/TangDou/AcWing/LIS/1014_2.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1014_2.cpp rename to TangDou/AcWing/LIS/1014_2.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1014_3.cpp b/TangDou/AcWing/LIS/1014_3.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1014_3.cpp rename to TangDou/AcWing/LIS/1014_3.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1016.cpp b/TangDou/AcWing/LIS/1016.cpp similarity index 87% rename from TangDou/AcWing_TiGao/T1/LIS/1016.cpp rename to TangDou/AcWing/LIS/1016.cpp index 1084f43..5cabba0 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/1016.cpp +++ b/TangDou/AcWing/LIS/1016.cpp @@ -5,7 +5,7 @@ using namespace std; int n; const int N = 100010; int a[N]; -int f[N]; +int f[N];//以第i个元素结尾的最大子序列和 int res; int main() { diff --git a/TangDou/AcWing_TiGao/T1/LIS/1016.md b/TangDou/AcWing/LIS/1016.md similarity index 95% rename from TangDou/AcWing_TiGao/T1/LIS/1016.md rename to TangDou/AcWing/LIS/1016.md index 6499db0..c3a16b3 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/1016.md +++ b/TangDou/AcWing/LIS/1016.md @@ -54,7 +54,6 @@ $f[i]$:以第$i$个元素结尾的最大子序列和 ### 三、$O(n^2)$实现代码 ```cpp {.line-numbers} -//运行时间: 31 ms #include using namespace std; @@ -62,7 +61,7 @@ using namespace std; int n; const int N = 100010; int a[N]; -int f[N]; +int f[N];//以第i个元素结尾的最大子序列和 int res; int main() { diff --git a/TangDou/AcWing_TiGao/T1/LIS/1017.md b/TangDou/AcWing/LIS/1017.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1017.md rename to TangDou/AcWing/LIS/1017.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/1017_PuSu.cpp b/TangDou/AcWing/LIS/1017_PuSu.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/1017_PuSu.cpp rename to TangDou/AcWing/LIS/1017_PuSu.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/1017_TanXin.cpp b/TangDou/AcWing/LIS/1017_TanXin.cpp similarity index 61% rename from TangDou/AcWing_TiGao/T1/LIS/1017_TanXin.cpp rename to TangDou/AcWing/LIS/1017_TanXin.cpp index b965294..5fadd0f 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/1017_TanXin.cpp +++ b/TangDou/AcWing/LIS/1017_TanXin.cpp @@ -21,32 +21,27 @@ int main() { fl = 0, gl = 0; cin >> n; - for (int i = 0; i < n; i++) cin >> a[i]; + for (int i = 1; i <= n; i++) cin >> a[i]; // 正着求 - f[0] = a[0]; - for (int i = 1; i < n; i++) { + for (int i = 1; i <= n; i++) { if (a[i] > f[fl]) f[++fl] = a[i]; else - *lower_bound(f, f + fl, a[i]) = a[i]; + *lower_bound(f + 1, f + 1 + fl, a[i]) = a[i]; } - // 前半程的结果 - res = fl; - // 反着求 - g[0] = a[n - 1]; - for (int i = n - 1; i >= 0; i--) { + for (int i = n; i; i--) { if (a[i] > g[gl]) g[++gl] = a[i]; else - *lower_bound(g, g + gl, a[i]) = a[i]; + *lower_bound(g + 1, g + 1 + gl, a[i]) = a[i]; } // pk的最大结果 - res = max(res, gl); + res = max(fl, gl); // 输出 - printf("%d\n", res + 1); + printf("%d\n", res); } return 0; } \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T1/LIS/187.cpp b/TangDou/AcWing/LIS/187.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/187.cpp rename to TangDou/AcWing/LIS/187.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/187.md b/TangDou/AcWing/LIS/187.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/187.md rename to TangDou/AcWing/LIS/187.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/272.md b/TangDou/AcWing/LIS/272.md similarity index 69% rename from TangDou/AcWing_TiGao/T1/LIS/272.md rename to TangDou/AcWing/LIS/272.md index bea07bf..903fe59 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/272.md +++ b/TangDou/AcWing/LIS/272.md @@ -44,9 +44,10 @@ $1≤N≤3000$,序列中的数字均不超过 $2^{31}−1$。 ### 二、前导知识 -[$AcWing$ $895$. 最长上升子序列](https://www.cnblogs.com/littlehb/p/15425546.html) +**[$AcWing$ $895$. 最长上升子序列](https://www.cnblogs.com/littlehb/p/15425546.html)** -**状态表示** $f[i]$表示从第一个数字开始算,以$a[i]$ **结尾** 的最长的上升序列长度。(以$a[i]$结尾的所有上升序列中属性为**最长**的那一个) +**状态表示** +$f[i]$表示从第一个数字开始算,以$a[i]$ **结尾** 的最长的上升序列长度。(以$a[i]$结尾的所有上升序列中属性为**最长**的那一个) **状态计算** @@ -57,7 +58,7 @@ f[i] = max(f[i], f[j] + 1) & 0 \le jb_k$$ +$$\large f[i][j]=max(f[i][j],f[i−1][k]+1),k∈[0,j−1],a_i=b_j,b_j>b_k$$ -如果直接按上述思路实现,需要三重循环: +按上述思路实现,需要三重循环: -```cpp {.line-numbers} -for (int i = 1; i <= n; i ++ ){ - for (int j = 1; j <= n; j ++ ){ - f[i][j] = f[i - 1][j]; //不管a[i]是否等于b[j],f[i][j]一定会从f[i-1][j]继承过来 - if (a[i] == b[j]){ - int maxv = 1; //最起码命中了一个a[i]==b[j],LCIS最少是1 - for (int k = 1; k < j; k ++ ) - if (a[i] > b[k]) // 不光是公共,还要上升 - maxv = max(maxv, f[i - 1][k] + 1); - f[i][j] = max(f[i][j], maxv); - } - } -} -``` -#### 实现代码$O(N^3)$ ```cpp {.line-numbers} #include using namespace std; @@ -122,7 +97,7 @@ const int N = 3010; int a[N], b[N]; int f[N][N]; int res; - +// 通过了 10/13个数据 // O(n^3) int main() { int n; @@ -138,14 +113,14 @@ int main() { f[i][j] = f[i - 1][j]; // ③ 如果恰好 a[i]==b[j],那么就可以发生转移 if (a[i] == b[j]) { - int maxv = 1; // 最起码a[i]==b[j],有一个数字是一样嘀~ + int mx = 1; // 最起码a[i]==b[j],有一个数字是一样嘀~ // f[i-1]是肯定的了,问题是b的前驱在哪里?需要枚举1~j-1 for (int k = 1; k < j; k++) - if (a[i] > b[k]) // 公共还不成,还需要上升 + if (b[j] > b[k]) // 需要上升 // 找出公共且最长的 - maxv = max(maxv, f[i - 1][k] + 1); + mx = max(mx, f[i - 1][k] + 1); // 更新答案 - f[i][j] = max(f[i][j], maxv); + f[i][j] = max(f[i][j], mx); } } int res = 0; @@ -158,9 +133,9 @@ int main() { ### 四、优化 -**$Q$:朴素办法超时($10/16$),如何优化?** +**$Q$:朴素办法超时($10/13$),如何优化?** -观察到,对于第二种状态转移:$f_{i,j}=max(f_{i,j},f_{i−1,k}+1) \ k∈[0,j−1],a_i=b_j,b_j>b_k$ +观察到,对于第二种状态转移:$f[i][j]=max(f[i][j],f[i−1][k]+1) \ k∈[0,j−1],a_i=b_j,b_j>b_k$ 每次用到的 **状态** 都是第 $i - 1$ 个阶段的 @@ -186,11 +161,11 @@ int main() { for (int i = 1; i <= n; i++) cin >> b[i]; for (int i = 1; i <= n; i++) { - int maxv = 1; + int mx = 1; for (int j = 1; j <= n; j++) { f[i][j] = f[i - 1][j]; - if (a[i] == b[j]) f[i][j] = max(f[i][j], maxv); - if (a[i] > b[j]) maxv = max(maxv, f[i - 1][j] + 1); + if (a[i] == b[j]) f[i][j] = mx; + if (a[i] > b[j]) mx = max(mx, f[i - 1][j] + 1); } } @@ -199,6 +174,7 @@ int main() { return 0; } + ``` ### 五、空间优化 diff --git a/TangDou/AcWing_TiGao/T1/LIS/272_1.cpp b/TangDou/AcWing/LIS/272_1.cpp similarity index 76% rename from TangDou/AcWing_TiGao/T1/LIS/272_1.cpp rename to TangDou/AcWing/LIS/272_1.cpp index 2695705..af9888f 100644 --- a/TangDou/AcWing_TiGao/T1/LIS/272_1.cpp +++ b/TangDou/AcWing/LIS/272_1.cpp @@ -5,7 +5,7 @@ const int N = 3010; int a[N], b[N]; int f[N][N]; int res; - +// 通过了 10/13个数据 // O(n^3) int main() { int n; @@ -21,14 +21,13 @@ int main() { f[i][j] = f[i - 1][j]; // ③ 如果恰好 a[i]==b[j],那么就可以发生转移 if (a[i] == b[j]) { - int maxv = 1; // 最起码a[i]==b[j],有一个数字是一样嘀~ + int mx = 1; // 最起码a[i]==b[j],有一个数字是一样嘀~ // f[i-1]是肯定的了,问题是b的前驱在哪里?需要枚举1~j-1 for (int k = 1; k < j; k++) - if (a[i] > b[k]) // 公共还不成,还需要上升 - // 找出公共且最长的 - maxv = max(maxv, f[i - 1][k] + 1); + if (a[i] > b[k]) // j可以接在k后面,那么可能的最大值为f[i-1][k]+1 + mx = max(mx, f[i - 1][k] + 1); // 更新答案 - f[i][j] = max(f[i][j], maxv); + f[i][j] = max(f[i][j], mx); } } int res = 0; diff --git a/TangDou/AcWing/LIS/272_2.cpp b/TangDou/AcWing/LIS/272_2.cpp new file mode 100644 index 0000000..b2b4152 --- /dev/null +++ b/TangDou/AcWing/LIS/272_2.cpp @@ -0,0 +1,30 @@ +#include + +using namespace std; +const int N = 3010; +int a[N], b[N]; +int f[N][N]; +int res; + +// O(n^2) +// f[i][j]—集合:考虑 a 中前 i 个数字,b 中前 j 个数字 ,且当前以 b[j] 结尾的子序列的方案 +int main() { + int n; + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + for (int i = 1; i <= n; i++) cin >> b[i]; + + for (int i = 1; i <= n; i++) { + int mx = 1; // 如果a[i]==b[j],那么LICS最小是1.如果下面的循环中没有一个if被执行,则mx没使上 + for (int j = 1; j <= n; j++) { + f[i][j] = f[i - 1][j]; // 先继承过来,现实含义:即使a[i]!=b[j],那么最长长度不会因为i的增加而变化,即f[i][j]=f[i-1][j] + if (a[i] == b[j]) f[i][j] = mx; + if (a[i] > b[j]) mx = max(mx, f[i - 1][j] + 1); + } + } + + for (int i = 1; i <= n; i++) res = max(res, f[n][i]); + printf("%d\n", res); + + return 0; +} diff --git a/TangDou/AcWing_TiGao/T1/LIS/272_YiWei.cpp b/TangDou/AcWing/LIS/272_YiWei.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/272_YiWei.cpp rename to TangDou/AcWing/LIS/272_YiWei.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/3549.cpp b/TangDou/AcWing/LIS/3549.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/3549.cpp rename to TangDou/AcWing/LIS/3549.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/3549.eddx b/TangDou/AcWing/LIS/3549.eddx similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/3549.eddx rename to TangDou/AcWing/LIS/3549.eddx diff --git a/TangDou/AcWing_TiGao/T1/LIS/3549.md b/TangDou/AcWing/LIS/3549.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/3549.md rename to TangDou/AcWing/LIS/3549.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/3662.cpp b/TangDou/AcWing/LIS/3662.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/3662.cpp rename to TangDou/AcWing/LIS/3662.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/3662.md b/TangDou/AcWing/LIS/3662.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/3662.md rename to TangDou/AcWing/LIS/3662.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/482.md b/TangDou/AcWing/LIS/482.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/482.md rename to TangDou/AcWing/LIS/482.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/482_1.cpp b/TangDou/AcWing/LIS/482_1.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/482_1.cpp rename to TangDou/AcWing/LIS/482_1.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/482_2.cpp b/TangDou/AcWing/LIS/482_2.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/482_2.cpp rename to TangDou/AcWing/LIS/482_2.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/482_3.cpp b/TangDou/AcWing/LIS/482_3.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/482_3.cpp rename to TangDou/AcWing/LIS/482_3.cpp diff --git a/TangDou/AcWing/LineDP/895.cpp b/TangDou/AcWing/LIS/895.cpp similarity index 57% rename from TangDou/AcWing/LineDP/895.cpp rename to TangDou/AcWing/LIS/895.cpp index 63a4b87..79b9b0f 100644 --- a/TangDou/AcWing/LineDP/895.cpp +++ b/TangDou/AcWing/LIS/895.cpp @@ -12,9 +12,10 @@ int main() { for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) { - f[i] = 1; + f[i] = 1; // 一个以i结尾的序列,最少可以是i自己,长度是1 for (int j = 1; j < i; j++) - if (a[i] > a[j]) f[i] = max(f[i], f[j] + 1); + if (a[i] > a[j]) // i可以接在j后面 + f[i] = max(f[i], f[j] + 1); // 借力于j res = max(res, f[i]); } printf("%d", res); diff --git a/TangDou/AcWing/LineDP/895.md b/TangDou/AcWing/LIS/895.md similarity index 100% rename from TangDou/AcWing/LineDP/895.md rename to TangDou/AcWing/LIS/895.md diff --git a/TangDou/AcWing/LineDP/895_WithPrintPath.cpp b/TangDou/AcWing/LIS/895_WithPrintPath.cpp similarity index 100% rename from TangDou/AcWing/LineDP/895_WithPrintPath.cpp rename to TangDou/AcWing/LIS/895_WithPrintPath.cpp diff --git a/TangDou/AcWing/LineDP/896.cpp b/TangDou/AcWing/LIS/896.cpp similarity index 100% rename from TangDou/AcWing/LineDP/896.cpp rename to TangDou/AcWing/LIS/896.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896.md b/TangDou/AcWing/LIS/896.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896.md rename to TangDou/AcWing/LIS/896.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_ErFen.cpp b/TangDou/AcWing/LIS/896_ErFen.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_ErFen.cpp rename to TangDou/AcWing/LIS/896_ErFen.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_ErFen_Inc_Dec.cpp b/TangDou/AcWing/LIS/896_ErFen_Inc_Dec.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_ErFen_Inc_Dec.cpp rename to TangDou/AcWing/LIS/896_ErFen_Inc_Dec.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_0.cpp b/TangDou/AcWing/LIS/896_FenWickTree_0.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_0.cpp rename to TangDou/AcWing/LIS/896_FenWickTree_0.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_1.cpp b/TangDou/AcWing/LIS/896_FenWickTree_1.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_1.cpp rename to TangDou/AcWing/LIS/896_FenWickTree_1.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_2.cpp b/TangDou/AcWing/LIS/896_FenWickTree_2.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_2.cpp rename to TangDou/AcWing/LIS/896_FenWickTree_2.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_3.cpp b/TangDou/AcWing/LIS/896_FenWickTree_3.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_FenWickTree_3.cpp rename to TangDou/AcWing/LIS/896_FenWickTree_3.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_WithPrintPath.cpp b/TangDou/AcWing/LIS/896_WithPrintPath.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_WithPrintPath.cpp rename to TangDou/AcWing/LIS/896_WithPrintPath.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/896_使用树状数组优化LIS问题.md b/TangDou/AcWing/LIS/896_使用树状数组优化LIS问题.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/896_使用树状数组优化LIS问题.md rename to TangDou/AcWing/LIS/896_使用树状数组优化LIS问题.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/897.cpp b/TangDou/AcWing/LIS/897.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/897.cpp rename to TangDou/AcWing/LIS/897.cpp diff --git a/TangDou/AcWing_TiGao/T1/LIS/897.md b/TangDou/AcWing/LIS/897.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/LIS/897.md rename to TangDou/AcWing/LIS/897.md diff --git a/TangDou/AcWing/LIS/LIS+LCS专题.md b/TangDou/AcWing/LIS/LIS+LCS专题.md new file mode 100644 index 0000000..217347e --- /dev/null +++ b/TangDou/AcWing/LIS/LIS+LCS专题.md @@ -0,0 +1,651 @@ +## $LIS$+$LCS$专题 + +#### 一、基础题 +**[$AcWing$ $895$. 最长上升子序列](https://www.acwing.com/problem/content/897/)** + +**时间复杂度** +$O(N^2)$ + +**状态表示** +$f[i]$:以$a[i]$结尾的最长上升子序列长度 + +**状态转移** +$f[i] = max(f[i], f[j] + 1)(a[i] > a[j])$ + +**初始值** +$f[i] = 1$ +> **解释**:一个以$i$结尾的序列,最少可以是$i$自己,长度是$1$ + +**代码** +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 1010; + +int n; +int a[N], f[N]; +int res; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + + for (int i = 1; i <= n; i++) { + f[i] = 1; // 一个以i结尾的序列,最少可以是i自己,长度是1 + for (int j = 1; j < i; j++) + if (a[i] > a[j]) // i可以接在j后面 + f[i] = max(f[i], f[j] + 1); // 借力于j + res = max(res, f[i]); + } + printf("%d", res); + return 0; +} + +``` + + +**[$AcWing$ $896$. 最长上升子序列 II ](https://www.acwing.com/problem/content/898/)** + +数据量增大:$N<=100000$ + +**思想** +对于同样长度的子串,希望它的末端越小越好,这样后面更易扩展它,使数列更长。 + +**时间复杂度** +$O(LogN*N)$ + +**状态表示** +$f[i]$表示 **长度为$i$** 的递增子序列中,**末尾元素最小** 的是$f[i]$ + +**答案** +$fl$ + +**特点与总结** +① $f[]$数组是一个单调上升的数组,这是二分的基础 +② 每个长度都争取替换掉前面记录数组中第一个大于等于自己的数字,以保证长度不变的情况下,数字最小。 + +**学习方法** +举栗子 + +**代码** +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 100010; + +int n, a[N]; + +// 数组模拟 +int f[N], fl; + +int main() { + cin >> n; + for (int i = 0; i < n; i++) cin >> a[i]; + + // 1、首个元素 + f[0] = a[0]; + + // 2、后续元素开始计算 + for (int i = 1; i < n; i++) { + if (a[i] > f[fl]) + f[++fl] = a[i]; + else + // 利用STL的二分,在f中查找第一个大于等于a[i]的值,并完成替换 + *lower_bound(f, f + fl, a[i]) = a[i]; + } + // 栈内元素数量就是答案 + printf("%d\n", fl + 1); + return 0; +} + +``` + + +**[$AcWing$ $897$. 最长公共子序列](https://www.acwing.com/problem/content/899/)** + +**状态表示** +$f[i][j]$:$a[]$以$i$结尾,$b[]$以$j$结尾的 **最长公共子序列长度** +> **说明**:没有说$a[i]$或者$b[j]$一定要出现在最长公共子序列当中!这个最长公共子序列,可能是$a[]$和$b[]$的一些前序组成的,$a[i],b[j]$也可能没有对结果产生贡献。 + +* 当$a[i]==b[j]$时,看一下两个字符串的前序,发现在少了$a[i],b[j]$后,转化为子问题$f[i-1][j-1]$,问题转化为$$f[i][j]=f[i-1][j-1]+1$$ + +* 当$a[i] \neq b[j]$时: + * 如果$a[i]$不产生贡献,那么把它干掉$f[i-1][j]$ + * 如果$b[j]$不产生贡献,那么把它干掉$f[i][j-1]$3 + +**答案** +$f[n][m]$ + +**代码** +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 1010; +int n, m; +char a[N], b[N]; +int f[N][N]; + +int main() { + // 递推式出现f[i-1][j-1],如果i,j从0开始会出现负值,所以下标从1开始 + cin >> n >> m >> a + 1 >> b + 1; + for (int i = 1; i <= n; i++) + for (int j = 1; j <= m; j++) { + if (a[i] == b[j]) + f[i][j] = f[i - 1][j - 1] + 1; + else + f[i][j] = max(f[i - 1][j], f[i][j - 1]); + } + printf("%d", f[n][m]); + return 0; +} +``` + +#### 二、进阶题 +**[$AcWing$ $1017$. 怪盗基德的滑翔翼](https://www.acwing.com/problem/content/1019/)** + +朴素$O(N^2)$版本 +```cpp {.line-numbers} +#include + +using namespace std; + +const int N = 110; +int n; // 楼房的个数 +int w[N]; // 楼房的高度数组 +int f[N]; // LIS结果数组,DP结果 + +int main() { + int T; + cin >> T; + while (T--) { + // 保持好习惯,多组测试数据,记得每次清空结果数组 + memset(f, 0, sizeof f); + int res = 0; + + cin >> n; + for (int i = 1; i <= n; i++) cin >> w[i]; + + // 从左到右,求一遍最长上升子序列[朴素O(N^2)版本] + for (int i = 1; i <= n; i++) { + f[i] = 1; + for (int j = 1; j < i; j++) + if (w[i] > w[j]) f[i] = max(f[i], f[j] + 1); + res = max(res, f[i]); + } + + // 反向求解 LIS问题 + for (int i = n; i >= 1; i--) { + f[i] = 1; + for (int j = n; j > i; j--) + if (w[i] > w[j]) f[i] = max(f[i], f[j] + 1); + res = max(res, f[i]); + } + + printf("%d\n", res); + } + return 0; +} +``` +优化$O(LogN*N)$版本 +```cpp {.line-numbers} +#include + +using namespace std; + +const int N = 110; +int n; // 楼房的个数 +int a[N]; // 楼房的高度数组 + +// 数组模拟栈 +int f[N], fl; +int g[N], gl; +int res; + +int main() { + int T; + cin >> T; + while (T--) { + // 保持好习惯,多组测试数据,记得每次清空结果数组 + memset(f, 0, sizeof f); + memset(g, 0, sizeof g); + fl = 0, gl = 0; + + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + + // 正着求 + for (int i = 1; i <= n; i++) { + if (a[i] > f[fl]) + f[++fl] = a[i]; + else + *lower_bound(f + 1, f + 1 + fl, a[i]) = a[i]; + } + + // 反着求 + for (int i = n; i; i--) { + if (a[i] > g[gl]) + g[++gl] = a[i]; + else + *lower_bound(g + 1, g + 1 + gl, a[i]) = a[i]; + } + // pk的最大结果 + res = max(fl, gl); + // 输出 + printf("%d\n", res); + } + return 0; +} +``` + +**[$AcWing$ $1014$. 登山](https://www.acwing.com/problem/content/1016/)** +```cpp {.line-numbers} +#include + +using namespace std; + +const int N = 1010; +int n; // 山的个数 +int a[N]; // 山的高度数组 +int f[N]; // 最长上升子序列 +int g[N]; // 最长下降子序列 +int res; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + + // 正向 + for (int i = 1; i <= n; i++) { + f[i] = 1; + for (int j = 1; j < i; j++) + if (a[i] > a[j]) f[i] = max(f[i], f[j] + 1); + } + // 反向 + for (int i = n; i >= 1; i--) { + g[i] = 1; + for (int j = n; j > i; j--) + if (a[i] > a[j]) g[i] = max(g[i], g[j] + 1); + } + + // 每个点,都可能是两者相加的最大位置处,所以,需要枚举每个点,每个点都有资格参评最优点 + // 因为最终的那个中间点,左边计算了一次,右边又计算了一次,需要减1去重复 + for (int i = 1; i <= n; i++) res = max(res, f[i] + g[i] - 1); + // 输出 + printf("%d\n", res); + return 0; +} +``` + +**[$AcWing$ $482$. 合唱队形](https://www.acwing.com/problem/content/484/)** +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 1010; +int n, a[N]; +int f[N], fl, p1[N]; +int g[N], gl, p2[N]; + +int res; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + + // 正向 + f[++fl] = a[1]; + p1[1] = 1; + + for (int i = 2; i <= n; i++) + if (a[i] > f[fl]) { + f[++fl] = a[i]; + p1[i] = fl; + } else { + int t = lower_bound(f + 1, f + fl + 1, a[i]) - f; + f[t] = a[i]; + p1[i] = t; + } + + // 反向 + g[++gl] = a[n]; + p2[n] = 1; + + for (int i = n - 1; i >= 1; i--) + if (a[i] > g[gl]) { + g[++gl] = a[i]; + p2[i] = gl; + } else { + int t = lower_bound(g + 1, g + gl + 1, a[i]) - g; + g[t] = a[i]; + p2[i] = t; + } + + for (int i = 1; i <= n; i++) res = max(res, p2[i] + p1[i] - 1); + + printf("%d\n", n - res); + return 0; +} +``` +**[$AcWing$ $1012$. 友好城市](https://www.acwing.com/problem/content/1014/)** +① 数对 +② 左端点排序 +③ 对于右端点组成的数组,求最长上升子序列长度 +```cpp {.line-numbers} +#include + +using namespace std; +typedef pair PII; +#define x first +#define y second +const int N = 5010; +PII a[N]; // 南岸和北岸的一对友好城市的坐标 +int f[N]; // 记录以f[i]为结尾的一对友好城市时的,不产生交叉的最多城市对数 +int n; // n组友好城市 +int res; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y; + sort(a + 1, a + 1 + n); // PII默认按第一维度first进行排序 + + // LIS + for (int i = 1; i <= n; i++) { + f[i] = 1; + for (int j = 1; j < i; j++) + if (a[i].y > a[j].y) + f[i] = max(f[i], f[j] + 1); + res = max(res, f[i]); + } + printf("%d\n", res); + return 0; +} +``` + +```cpp {.line-numbers} +#include + +using namespace std; +typedef pair PII; +#define x first +#define y second + +const int N = 5010; +PII a[N]; // 南岸和北岸的一对友好城市的坐标 +int f[N], fl; // 数组模拟栈 +int n; // n组友好城市 +int res; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y; + sort(a + 1, a + 1 + n); + + f[++fl] = a[1].y; + for (int i = 2; i <= n; i++) { + if (a[i].y > f[fl]) + f[++fl] = a[i].y; + else + *lower_bound(f + 1, f + 1 + fl, a[i].y) = a[i].y; + } + + printf("%d\n", fl); + return 0; +} +``` + +**[$AcWing$ $1016$. 最大上升子序列和](https://www.acwing.com/problem/content/1012/)** + +```cpp {.line-numbers} +#include +using namespace std; + +// 最大上升子序列和 +int n; +const int N = 100010; +int a[N]; +int f[N];//以第i个元素结尾的最大子序列和 +int res; + +int main() { + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + + for (int i = 1; i <= n; i++) { + f[i] = a[i]; // 最大上升子序列(个数)这里是1,此处是a[i] + for (int j = 1; j < i; j++) + // 最大上升子序列(个数)这里是加1,此处是+a[i] + if (a[i] > a[j]) f[i] = max(f[i], f[j] + a[i]); + res = max(res, f[i]); + } + printf("%d ", res); + return 0; +} +``` +**魔改 最长上升子序列和** + +**[$AcWing$ $1010$. 拦截导弹](https://www.acwing.com/problem/content/1012/)** + +> **题目要求**:但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。 + +**数组含义** +$q[],ql$:已经创建了$ql$套导弹系统,$q[i]$中记录的是第$i$套导弹系统的最大拦截高度 + +**举栗子,总结规律** +$q[0]:5$ +$q[1]:6$ +> **举的这个栗子对吗?** +> 我们思考一下:原来有一套导弹拦截系统,上次的高度是$5$,现在第二颗导弹的高度是$6$,根据题目要求,它不能高于前一发的高度,所以只能再开一个导弹拦截系统,所以,第二个是$6$是正确的。 + +现在来了一个高度=$4$,根据上面的原则,可以接在$5$后面,也可以接在$6$后面,我们为了不浪费$6$,就选择了接在$5$后面,放到$q[0]$里,修改$q[0]=4$ +$q[0]:4$ +$q[1]:6$ +原来的数组是单调上升的,修改后值也是在上下夹着中间的,也依然是单调上升的。 + +再比如: +$q[0]:4$ +$q[1]:6$ +$q[2]:7$ +现在来了一个$a[i]=5$,我们肯定要修改$q[1]=5$,变为: + +$q[0]:4$ +$q[1]:5$ +$q[2]:7$ +原来的数组是 **单调上升** 的,修改后也依然是 **单调上升** 的。 + +既然有这个规律,那么就可以使用二分快速查找大于等于$a[i]$的位置$p$了: + +```cpp {.line-numbers} +#include +using namespace std; + +const int N = 1010; + +int a[N], f[N]; // 每个导弹的高度,f[i]:以a[i]结尾的最长不升子序列长度 +int q[N], ql; // 需要ql套拦截系统,每个拦截系统最后一个拦截高度为q[i] +int n, res; + +int main() { + while (cin >> a[n]) n++; + // 第一问 + for (int i = 0; i < n; i++) { + f[i] = 1; + for (int j = 0; j < i; j++) + if (a[i] <= a[j]) // 如果前面的比当前的大,说明是不升序列 + f[i] = max(f[i], f[j] + 1); + res = max(res, f[i]); + } + // 第二问 + for (int i = 0; i < n; i++) { + int p = lower_bound(q, q + ql, a[i]) - q; + if (p == ql) // 如果没有找到可以接在后面的导弹拦截系统,那么需要创建一套新的拦截系统 + q[ql++] = a[i]; + else + q[p] = a[i]; // 否则就直接接到找到的第k套拦截系统的后面,那么,第k套拦截系统的最后一个拦截高度=q[k]=h[i] + } + // 输出最长不升序列长度,即:最多能拦截的导弹数 + printf("%d\n%d\n", res, ql); + return 0; +} +``` + +**[$AcWing$ $187$. 导弹防御系统](https://www.acwing.com/problem/content/189/)** + +导弹拦截系统的拦截高度即可以 严格单调上升,又可以严格单调下降,此时,用$LIS$模型是无法解决问题的,考虑到$n<50$,可以用$dfs+$剪枝 + +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 55; +const int INF = 0x3f3f3f3f; +int n; +int a[N]; +int up[N], down[N]; +int res; + +// 本题关键字:贪心+爆搜 + +/* + 功能:暴搜所有可能,配合剪枝,找出最少的拦截系统数量 + u: 第几个导弹 + ul: 上升拦截系统的数量,配合up 数组使用 + dl: 下降拦截系统的数量,配合down数组使用 + */ +void dfs(int u, int ul, int dl) { + if (ul + dl >= res) return; // 伟大的剪枝,不剪枝会TLE~,中途发现已经大于等于res的情况,就返回 + if (u == n) { // 走完全程,收集答案 + res = min(res, ul + dl); // 因为上面的剪枝,把ul+dl>=res的全干掉了,能到这里的,都是= a[u]) break; + + t = down[k]; // 保留现场 + down[k] = a[u]; + if (k < dl) + dfs(u + 1, ul, dl); + else + dfs(u + 1, ul, dl + 1); + down[k] = t; // 回溯 +} + +int main() { + while (cin >> n, n) { // 多套数据,输入n=0时停止 + for (int i = 0; i < n; i++) cin >> a[i]; + res = INF; // 防御系统的最少数量 + dfs(0, 0, 0); // 开始深搜,更新res的值 + printf("%d\n", res); + } + return 0; +} + +``` + + +**[$AcWing$ $272$. 最长公共上升子序列](https://www.acwing.com/problem/content/274/)** + + +```cpp {.line-numbers} +#include +using namespace std; + +const int N = 3010; +int a[N], b[N]; +int f[N][N]; +int res; +// 通过了 10/13个数据 +// O(n^3) +int main() { + int n; + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + for (int i = 1; i <= n; i++) cin >> b[i]; + + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) { + // ① 二维DP打表的一般套路,都是可以直接从上一行继承的 + // ② 从题意出发,就是a中前i个数字,b中前j个数字,且以b[j]结尾的子序列中长度最大的 + // 那么,a中多整出一个数字来,最起码也是f[i-1][j]的值,不能更小 + f[i][j] = f[i - 1][j]; + // ③ 如果恰好 a[i]==b[j],那么就可以发生转移 + if (a[i] == b[j]) { + int mx = 1; // 最起码a[i]==b[j],有一个数字是一样嘀~ + // f[i-1]是肯定的了,问题是b的前驱在哪里?需要枚举1~j-1 + for (int k = 1; k < j; k++) + if (a[i] > b[k]) // j可以接在k后面,那么可能的最大值为f[i-1][k]+1 + mx = max(mx, f[i - 1][k] + 1); + // 更新答案 + f[i][j] = max(f[i][j], mx); + } + } + int res = 0; + // a数组肯定是火力全开到n就行,b数组中的位置就需要枚举了 + for (int i = 1; i <= n; i++) res = max(res, f[n][i]); + printf("%d\n", res); + return 0; +} +``` +前面之所以把$b[j]$换成$a[i]$,是因为方便现在考虑。 + +由于在枚举计算$f[i][j]$时,却用到的是和内层循环(即$b[j]$)无关的,只和外层循环(即$a[i]$)有关,而我们在计算$f[i][j]$,每次都要用到前$j−1$个数中小于$a[i]$的$f[i-1][k]$最大值,所以我们可以用一个变量$mx$不断更新它来保存前$j−1$的答案,就可以避免重复计算,从而降低时间复杂度。 + +$O(N^2)$ + +```cpp {.line-numbers} +#include + +using namespace std; +const int N = 3010; +int a[N], b[N]; +int f[N][N]; +int res; + +// O(n^2) +// f[i][j]—集合:考虑 a 中前 i 个数字,b 中前 j 个数字 ,且当前以 b[j] 结尾的子序列的方案 +int main() { + int n; + cin >> n; + for (int i = 1; i <= n; i++) cin >> a[i]; + for (int i = 1; i <= n; i++) cin >> b[i]; + + for (int i = 1; i <= n; i++) { + int mx = 1; // 如果a[i]==b[j],那么LICS最小是1.如果下面的循环中没有一个if被执行,则mx没使上 + for (int j = 1; j <= n; j++) { + f[i][j] = f[i - 1][j]; // 先继承过来,现实含义:即使a[i]!=b[j],那么最长长度不会因为i的增加而变化,即f[i][j]=f[i-1][j] + if (a[i] == b[j]) f[i][j] = mx; + if (a[i] > b[j]) mx = max(mx, f[i - 1][j] + 1); + } + } + + for (int i = 1; i <= n; i++) res = max(res, f[n][i]); + printf("%d\n", res); + + return 0; +} +``` +[最长上升子序列 ($LIS$) 详解+例题模板 (全)](https://blog.csdn.net/lxt_Lucia/article/details/81206439) diff --git a/TangDou/AcWing/LineDP/896.md b/TangDou/AcWing/LineDP/896.md deleted file mode 100644 index 41be38b..0000000 --- a/TangDou/AcWing/LineDP/896.md +++ /dev/null @@ -1,210 +0,0 @@ -##[$AcWing$ $896$. 最长上升子序列 II](https://www.acwing.com/problem/content/description/898/) - -### 一、题目描述 - -给定一个长度为 $N$ 的数列,**求数值严格单调递增的子序列的长度最长** 是多少。 - -**输入格式** -第一行包含整数 $N$。 - -第二行包含 $N$ 个整数,表示完整序列。 - -**输出格式** -输出一个整数,表示最大长度。 - -**数据范围** -$1≤N≤100000$, -$−10^9≤数列中的数≤10^9$ - -**输入样例:** -```cpp {.line-numbers} -7 -3 1 2 1 8 5 6 -``` - -**输出样例**: -```cpp {.line-numbers} -4 -``` - - - - -### 二、贪心+二分优化 - -#### 1、与朴素版本的区别 - -> **朴素版本状态表示**: -> - 集合:$f[i]$表示从第一个数字开始算,以 $a[i]$ 结尾 的最长的上升序列长度。 -> - 属性:$max$ - - -前一版本:$N≤1000$,本题要求:$N≤100000$ - -$N$的数据范围大了$100$倍,前一版本动态规划代码的时间复杂度是$O(N^2)$,$1000^2=1000000$,是$1e6$,是可以$1$秒过的,但如果是$100000^2=10000000000$,是$1e10$,超时,需要要优化~ - - - -#### 2、贪心+二分算法 - ->核心思想: -对于同样长度的子串,希望它的末端越小越好,这样后面有更多机会拓展它,才有可能使得数列更长。 - -> **状态表示**: -> - 集合:$f[i]$表示长度为$i$的递增子序列中,末尾元素最小的是$f[i]$ -> - 属性:$min$ - -**算法步骤** -* 扫描每个原序列中的数字: - * 如果$f$中的最后一个数字$f[idx]$小于当前数字$a[i]$,那么就在$f$的最后面增加$a[i]$ - - * 如果$a[i]$小于$f[idx]$,在$f$中查找并替换第一个大于等于它元素 - -**举栗子模拟** -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | --- | --- | --- | --- | --- | --- | - -
- - -开始时$f[]$为空,数字$3$进入序列 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | ---------------------------- | --- | --- | --- | --- | --- | --- | - -| $f$ | $3$ | -| --- | ------------------------------------------ | - -
- - -$1$ 比 $3$ 小, $3$出序列 ,$1$入序列 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | ------------------------------ | --- | --- | --- | --- | --- | - - -| $f$ | $1$ | -| --- | ------------------------------------------ | - -
- - -$2$ 比 $1$ 大,$2$入序列 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | --- | ----------------------------- | --- | --- | --- | --- | - - -| $f$ | $1$ | $2$ | -| --- | --- | ------------------------------------------ | - -
- - -$1$ 比 $2$ 小,在$f$中找到第一个大于等于$1$的位置,并替换掉原来的数字 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | --- | --- | ---------------------------- | --- | --- | --- | - - -| $f$ | $1$ | $2$ | -| --- | ------------------------------------------ | --- | -
- - -$8$ 比 $2$ 大 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | --- | --- | --- | ---------------------------- | --- | --- | - - -| $f$ | $1$ | $2$ | $8$ | -| --- | --- | --- | ------------------------------------------ | -
- - -$5$ 比 $8$ 小,在$f$中找到第一个大于等于$5$的数字,并替换掉原来的数字 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | --- | --- | --- | --- | ---------------------------- | --- | - - -| $f$ | $1$ | $2$ | $5$ | -| --- | --- | --- | ------------------------------------------ | -
- - -$6$ 比 $5$ 大 - -
- -| $arr$ | $3$ | $1$ | $2$ | $1$ | $8$ | $5$ | $6$ | -| ----- | --- | --- | --- | --- | --- | --- | ------------------------------------------- | - - -| $f$ | $1$ | $2$ | $5$ | $6$ | -| --- | --- | --- | --- | ------------------------------------------ | -
- - -
$f$ 的长度$idx$就是最长递增子序列的长度
- - -#### 3、时间复杂度 -$$\large O(N*logN)$$ - -### 四、实现代码 -```cpp {.line-numbers} -#include - -using namespace std; -const int N = 100010; - -int n, a[N]; - -// 数组模拟栈 -int f[N], fl; - -int main() { - cin >> n; - for (int i = 0; i < n; i++) cin >> a[i]; - - // 1、首个元素入栈 - f[0] = a[0]; - - // 2、后续元素开始计算 - for (int i = 1; i < n; i++) { - if (a[i] > f[fl]) - f[++fl] = a[i]; - else - // 利用STL的二分,在f中查找第一个大于等于a[i]的值,并完成替换 - *lower_bound(f, f + fl, a[i]) = a[i]; - } - // 栈内元素数量就是答案 - printf("%d\n", fl + 1); - return 0; -} -``` \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1015.md b/TangDou/AcWing/NumberTriangles/1015.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1015.md rename to TangDou/AcWing/NumberTriangles/1015.md diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1015_Dfs.cpp b/TangDou/AcWing/NumberTriangles/1015_Dfs.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1015_Dfs.cpp rename to TangDou/AcWing/NumberTriangles/1015_Dfs.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1015_Dfs_JiYIHua.cpp b/TangDou/AcWing/NumberTriangles/1015_Dfs_JiYIHua.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1015_Dfs_JiYIHua.cpp rename to TangDou/AcWing/NumberTriangles/1015_Dfs_JiYIHua.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1015_ErWei.cpp b/TangDou/AcWing/NumberTriangles/1015_ErWei.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1015_ErWei.cpp rename to TangDou/AcWing/NumberTriangles/1015_ErWei.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1015_YiWei.cpp b/TangDou/AcWing/NumberTriangles/1015_YiWei.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1015_YiWei.cpp rename to TangDou/AcWing/NumberTriangles/1015_YiWei.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1018.md b/TangDou/AcWing/NumberTriangles/1018.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1018.md rename to TangDou/AcWing/NumberTriangles/1018.md diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1018_ErWei.cpp b/TangDou/AcWing/NumberTriangles/1018_ErWei.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1018_ErWei.cpp rename to TangDou/AcWing/NumberTriangles/1018_ErWei.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1018_YiWei.cpp b/TangDou/AcWing/NumberTriangles/1018_YiWei.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1018_YiWei.cpp rename to TangDou/AcWing/NumberTriangles/1018_YiWei.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1027.md b/TangDou/AcWing/NumberTriangles/1027.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1027.md rename to TangDou/AcWing/NumberTriangles/1027.md diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1027_0.cpp b/TangDou/AcWing/NumberTriangles/1027_0.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1027_0.cpp rename to TangDou/AcWing/NumberTriangles/1027_0.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1027_1.cpp b/TangDou/AcWing/NumberTriangles/1027_1.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1027_1.cpp rename to TangDou/AcWing/NumberTriangles/1027_1.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/1027_2.cpp b/TangDou/AcWing/NumberTriangles/1027_2.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/1027_2.cpp rename to TangDou/AcWing/NumberTriangles/1027_2.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/275.cpp b/TangDou/AcWing/NumberTriangles/275.cpp similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/275.cpp rename to TangDou/AcWing/NumberTriangles/275.cpp diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/275.md b/TangDou/AcWing/NumberTriangles/275.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/275.md rename to TangDou/AcWing/NumberTriangles/275.md diff --git a/TangDou/AcWing_TiGao/T1/NumberTriangles/数字三角形专题.md b/TangDou/AcWing/NumberTriangles/数字三角形专题.md similarity index 100% rename from TangDou/AcWing_TiGao/T1/NumberTriangles/数字三角形专题.md rename to TangDou/AcWing/NumberTriangles/数字三角形专题.md diff --git a/TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp b/TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp deleted file mode 100644 index c79570b..0000000 --- a/TangDou/AcWing_TiGao/T1/LIS/1010_TanXin.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include -using namespace std; - -const int N = 1010; - -int a[N], f[N]; // 每个导弹的高度,f[i]:以a[i]结尾的最长不升子序列长度 -int q[N], ql; // 需要ql套拦截系统,每个拦截系统最后一个拦截高度为q[i] -int n, res; - -int main() { - while (cin >> a[n]) n++; - // 第一问 - for (int i = 0; i < n; i++) { - f[i] = 1; - for (int j = 0; j < i; j++) - if (a[i] <= a[j]) // 如果前面的比当前的大,说明是不升序列 - f[i] = max(f[i], f[j] + 1); - res = max(res, f[i]); - } - // 第二问 - for (int i = 0; i < n; i++) { - /* 1、现有已经创建了ql套导弹系统 - 2、算法思路: - (1) 在已有的所有导弹拦截系统中找到大于当前高度,并且最小的那个,把当前导弹用这套拦截系统进行拦截 - (2) 如果找不到这样的拦截系统,说明当前所有拦截系统的最小拦截高度都小于当前导弹,都无法利用,必须新开一个拦截系统。 - (3) 也就是说,只有前面拦截系统的最后一个拦截高度,都小于当前高度时,才会创建新的,所以,后面的拦截系统,它的尾巴值应该是最大的 - (4) 比如: - q[0]:5 - q[1]:6 - 现在来了一个高度=4,根据上面的原则,应该放到q[0]里,修改q[0]=4 - q[0]:4 - q[1]:6 - 原来的数组是单调上升的,修改后也依然是单调上升的。 - - 再比如: - q[0]:4 - q[1]:6 - q[2]:7 - 现在来了一个a[i]=5,我们肯定要修改q[1]=5,变为: - - q[0]:4 - q[1]:5 - q[2]:7 - 原来的数组是单调上升的,修改后也依然是单调上升的。 - - 既然有这个规律,那么就可以使用二分快速查找大于等于a[i]的位置p了: - */ - int p = lower_bound(q, q + ql, a[i]) - q; - if (p == ql) // 如果没有找到可以接在后面的导弹拦截系统,那么需要创建一套新的拦截系统 - q[ql++] = a[i]; - else - q[p] = a[i]; // 否则就直接接到找到的第k套拦截系统的后面,那么,第k套拦截系统的最后一个拦截高度=q[k]=h[i] - } - // 输出最长不升序列长度,即:最多能拦截的导弹数 - printf("%d\n%d\n", res, ql); - return 0; -} \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T1/LIS/272_2.cpp b/TangDou/AcWing_TiGao/T1/LIS/272_2.cpp deleted file mode 100644 index 88309d5..0000000 --- a/TangDou/AcWing_TiGao/T1/LIS/272_2.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include - -using namespace std; -const int N = 3010; -int a[N], b[N]; -int f[N][N]; -int res; - -// O(n^2) -int main() { - int n; - cin >> n; - for (int i = 1; i <= n; i++) cin >> a[i]; - for (int i = 1; i <= n; i++) cin >> b[i]; - - for (int i = 1; i <= n; i++) { - int maxv = 1; - for (int j = 1; j <= n; j++) { - f[i][j] = f[i - 1][j]; - if (a[i] == b[j]) f[i][j] = maxv; - if (a[i] > b[j]) maxv = max(maxv, f[i - 1][j] + 1); - } - } - - for (int i = 1; i <= n; i++) res = max(res, f[n][i]); - printf("%d\n", res); - - return 0; -} diff --git a/TangDou/AcWing_TiGao/T1/LIS/896.cpp b/TangDou/AcWing_TiGao/T1/LIS/896.cpp deleted file mode 100644 index c892b3e..0000000 --- a/TangDou/AcWing_TiGao/T1/LIS/896.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include - -using namespace std; -const int N = 100010; - -int n, a[N]; - -// 数组模拟栈 -int f[N], fl; - -int main() { - cin >> n; - for (int i = 0; i < n; i++) cin >> a[i]; - - // 1、首个元素入栈 - f[0] = a[0]; - - // 2、后续元素开始计算 - for (int i = 1; i < n; i++) { - if (a[i] > f[fl]) - f[++fl] = a[i]; - else - // 利用STL的二分,在f中查找第一个大于等于a[i]的值,并完成替换 - *lower_bound(f, f + fl, a[i]) = a[i]; - } - // 栈内元素数量就是答案 - printf("%d\n", fl + 1); - return 0; -} \ No newline at end of file diff --git a/TangDou/AcWing_TiGao/T1/LIS/LIS+LCS专题.md b/TangDou/AcWing_TiGao/T1/LIS/LIS+LCS专题.md deleted file mode 100644 index 331b61f..0000000 --- a/TangDou/AcWing_TiGao/T1/LIS/LIS+LCS专题.md +++ /dev/null @@ -1,103 +0,0 @@ -## $LIS$+$LCS$专题 - -#### 基础题 -**[$AcWing$ $895$. 最长上升子序列](https://www.acwing.com/problem/content/897/)** - -$O(N^2)$算法 - -**状态表示** -$f[i]$:以$a[i]$结尾的最长上升子序列长度 - -**状态转移** -```cpp {.line-numbers} - for (int i = 1; i <= n; i++) { - f[i] = 1; //只有a[i]一个数 - for (int j = 1; j < i; j++) - if (a[j] < a[i]) f[i] = max(f[i], f[j] + 1); - } -``` -**答案** -```cpp {.line-numbers} -for (int i = 1; i <= n; i++) res = max(res, f[i]); -``` - - -**[$AcWing$ $896$. 最长上升子序列 II ](https://www.acwing.com/problem/content/898/)** - -数据量增大:$N<=100000$ -$O(LogN*N)$算法 - -```cpp {.line-numbers} - // 1、首个元素入栈 -f[0] = a[0]; - -// 2、后续元素开始计算 -for (int i = 1; i < n; i++) { - if (a[i] > f[fl]) - f[++fl] = a[i]; - else - //利用STL的二分,在f中查找第一个大于等于a[i]的值,并完成替换 - *lower_bound(f, f + fl, a[i]) = a[i]; -} -``` - -也可以这样写 -```cpp {.line-numbers} -memset(f,-0x3f,sizeof f); - -// 2、后续元素开始计算 -for (int i = 1; i <= n; i++) { - if (a[i] > f[fl]) - f[++fl] = a[i]; - else - //利用STL的二分,在f中查找第一个大于等于a[i]的值,并完成替换 - *lower_bound(f + 1, f + 1 + fl, a[i]) = a[i]; -} -``` - -很明显,第一种写法性能更高,第二种写法有点暴力。 - -**状态表示** -$f[i]$表示长度为$i$的递增子序列中,末尾元素最小的是$f[i]$ - -**答案** -$fl$ - -**状态转移** -① $f[]$数组是一个单独上升的数组,这是可以二分的基础 -② 每个长度都争取替换掉前面记录数组中第一个大于等于自己的数字,以保证长度不变的情况下,数字最小,因为只有最小才能让后面的其它数字更容易接上去,机会才能更多。 - -**[$AcWing$ $897$. 最长公共子序列](https://www.acwing.com/problem/content/899/)** - -**状态表示** -定义$f[i][j]$是$a[]$以$i$结尾,$b[]$以$j$结尾的**最长公共子序列长度** -> **说明**:没有说$a[i]$或者$b[j]$一定要出现在最长公共子序列当中!这个最长公共子序列,可能是$a[]$和$b[]$的一些前序组成的,$a[i],b[j]$也可能没有对结果产生贡献。 - -* 当$a[i]==b[j]$时,看一下两个字符串的前序,发现在少了$a[i],b[j]$后,转化为子问题$f[i-1][j-1]$,问题转化为$$f[i][j]=f[i-1][j-1]+1$$ - -* 当$a[i] \neq b[j]$时: - * 如果$a[i]$不产生贡献,那么把它干掉$f[i-1][j]$ - * 如果$b[j]$不产生贡献,那么把它干掉$f[i][j-1]$ -```cpp {.line-numbers} -for (int i = 1; i <= n; i++) - for (int j = 1; j <= m; j++) { - if (a[i] == b[j]) - f[i][j] = f[i - 1][j - 1] + 1; - else - f[i][j] = max(f[i - 1][j], f[i][j - 1]); - } -``` -**答案** -$f[n][m]$ - -#### 进阶题 -AcWing 1017. 怪盗基德的滑翔翼 -AcWing 1014. 登山 -AcWing 482. 合唱队形 -AcWing 1012. 友好城市 -AcWing 1016. 最大上升子序列和 -AcWing 1010. 拦截导弹 -AcWing 187. 导弹防御系统 -AcWing 272. 最长公共上升子序列 - -[最长上升子序列 ($LIS$) 详解+例题模板 (全)](https://blog.csdn.net/lxt_Lucia/article/details/81206439) diff --git a/TangDou/LanQiaoBei/2023年12月STEMA C++组中高级真题.pdf b/TangDou/LanQiaoBei/2023年12月STEMA C++组中高级真题.pdf new file mode 100644 index 0000000..556d594 Binary files /dev/null and b/TangDou/LanQiaoBei/2023年12月STEMA C++组中高级真题.pdf differ