2023/8刷题记录
2023/8刷题记录
luogu-P6885
向黑板上写数字,左右写,求所有序列的最长 \(LIS\) 并统计 \(LIS\) 的个数。
向左边放和向右边放相当于把一个序列拆成两个子序列,然后把第一个翻转接在第二个前面。
整个序列的 \(LIS\) 就相当于第一个序列的 \(LDS\) 和第二个子序列的 \(LIS\) 接起来,但要保证开头为哦那个一个数。
枚举每一个 \(a_i\) 用 \(f_i,g_i\) 记录 \(LIS,LDS\) 以及用 \(cntf_i,cntg_i\) 记录个数,整个\(LIS\) 为 \(f_i+g_i-1\),答案为 \(cntf_i\times cntg_i\times 2^{n-len_{LIS}}\)(因为还有一些不是 \(LIS\) 的数字可以随便放)。
经验:序列左右放,拆开。
luogu-P7154
把 \(n\) 头奶牛 \(s_i\) 放进 \(n\) 个牛棚 \(t_i\) ,能放进去为 \(s_i\leq t_i\),求极大匹配(看题)。
计数题。
把牛棚和奶牛从小到大排序,并且保证相同大小的奶牛和牛棚要奶牛在前。
令 $f_{i,j,0/1} $ 表示当前考虑了第 \(i\) 个牛或牛棚,其中有 \(j\) 头奶牛没有分配牛棚,是否考虑过不被匹配的奶牛。
对于每个 \(i\) 分别考虑为牛和牛棚的情况,进行状态转移(转移略,可根据题目得出具体看代码)。
考虑到 \(1\leq N \leq 3000\) 可能会 \(MLE\) 所以可以滚动数组。
经验:状态优化,把状态和约束同时处理。
luogu-P8863
给定一个长度为 \(n\) 的序列 \(b\) 和一个长度为 \(n\) 的空数组 \(n\) 通过每次把两个 \(a_i+1,a_j+1(i\ne j)\) 来使 \(a=b\),求方案数。
计数。首先求出操作次数,题目可以简化成构造一个 \(n\times m\) 的棋盘,放若干棋子,使得每一列都有两个棋子,第 \(i\) 行为 \(b_i\)。
则按行处理,\(f_{i,j}\) 为前 \(i\) 行,有 \(j\) 列有两个棋子。显然可以通过计算得出每列有一个棋子的个数 \(k\) 和没有棋子的个数 \(l\)。
处理第 \(i\) 枚举行,枚举一个 \(u\) ,有 \(u\) 个棋子放在了有一个棋子的列,显然组合数。
经验:转化棋盘,组合数。
luogu-CF1363F
题意见链接
显然可以转化成每次把一个 \(s_i\) 往前移动。又因为显然不会重复移动一个再付,所以相当于拿出一些字符,然后再放进去。并且向前移动。
设 \(f_{i,j}\) 为考虑了 \(s\) 的前缀 \(i\) ,\(t\) 的前缀 \(j\) ,拿出多少个使得它们匹配。
考虑转移
当 \(s_i=t_j,f_{i,j} \gets f_{i-1,j-1}\);
把 \(s_i\) 放到前面去 \(f_{i,j} \gets f_{i-1,j}+1\);
把后面的一个放到前面,要满足条件是前 \(i\) 个 \(s\) 中 \(t_j\) 的数量小于前 \(j\) 个 \(t\) 中 \(t_j\) 的数量。
luogu-CF1188C
题意见链接
设 \(f(x)\) 为美观度为 \(x\) 的子序列个数,令 \(F(x)\) 为美观度 \(\geq x\) 的子序列个数,而答案
所以把 \(a\) 从小到大排序
枚举 \(x\)。
设 \(dp_{i,j}\) 为考虑前 \(i\) 个数,选择了 \(j\) 个数且美观度 \(\geq x\) 的序列个数。
转移时枚举 \(k\),满足 \(a_i-a_k\geq x\) ,有 \(dp_{i,j} \gets dp_{i,j}+dp_{k,j-1}\),可使用前缀和优化。
经验:式子转化,前缀和优化
luogu-P7985
题意见链接
\(T=1\) 时经典题,略。
\(T=2\)
按照牛的位置从小到大考虑。
设 \(f_{i,j,* }\) 为考虑到第 \(i\) 头 \(H\) 和第 \(j\) 头 \(G\) 且匹配,但是还要记录上一头失配牛的位置。
注意到匹配和失配位置不是很重要,所以设 \(f_{i,j,0/1}\) 为考虑到第 \(i\) 头 \(H\) 和第 \(j\) 头 \(G\),最后一头失配的是第 \(i\) 头牛 \(H\) 还是第 \(j\) 头牛 \(G\) 。
枚举下一头失配的牛,并将之前的匹配,枚举一个 \(l\) 匹配数,转移就可以了,时间有点高,对 \(l\) 进行预处理就行了。
经验:考虑实际应有状态。
luogu-CF1768F
题意见链接
特别好的 \(dp\) 题,性质极其有趣。
观察到 \(a_i\leq n\)。
第一个性质是如果跳跃的话,最小值一定是 \(a_i\) 或 \(a_j\),否则从 \(i\) 跳到最小值,再从最小值跳到 \(j\) 一定代价更优。
第二个性质是每次跳跃步数不会超过 $\left \lfloor \frac{n}{a_{i}} \right \rfloor $,证明易证。
根据前面的两条性质可以推得时间复杂度为 \(O(n\sqrt{n})\) ,可以通过。