DP 题集 1
关于 DP 的一些题目php
参考资料
DP
- Rain and Umbrellas
- Mr. Kitayuta, the Treasure Hunter
- Power of String 首先咱们最多只会在一种字母中选择部分个,不然要么都选,要么都不选。以及咱们必定会把其余字母转化成一种字母。枚举要转化成的字母以及可能选部分的字母,而后就是01背包DP。复杂度\(O(26^3k)\)
- Fibonacci String Subsequences 对于这类字符串计数DP,通常就要考虑怎么去拼接字符串,DP的状态和字符串的子串有关。\(dp[i][l][r]\) 表示到第 \(i\) 个 Fibonacci 串时,包含了目标串的子串 \([l,r]\) 的子序列的个数。
- Gerald and Giant Chess 考虑到 \(k=2000\),因此 DP 的状态必然是和障碍物有关的,\(dp[i]\)表示到达第 \(i\) 个障碍物的路径上没有通过其它障碍物的方案数。
- Buggy Robot \(dp[x][y][i]\) 表示到 \((x,y)\) 这个点,在字符串中走到了第 \(i\) 个位置的最小花费。在 \(BFS\) 中进行状态转移,转移复杂度 \(O(1)\)。
- Group Projects 学到一个DP姿式。分组计数,\(dp[i][j][k]\)表示到第 \(i\) 我的时,有 \(j\) 个组仍是开放的(便可以被选择)不公平的值的和为 \(k\) 时的方案数。关键就是开放的组这一维,枚举 \(a[i]\) ,咱们能够去定义他的行为,是独自成组?仍是加入别的组?仍是新建一个开放的组?仍是加入一个组并关闭这个组?显然不一样的行为对应不一样的状态转移。还有因为咱们知道了开放的组的数量\(j\) ,考虑 \((a[i]-a[i-1])*j\) (\(i\neq0\))(\(a\) 数组先排序) ,就是那些仍然开放的组须要加的不公平的值的和。
- Increase Sequence \(dp[i][j]\) 表示到第 \(i\) 个数时,有 \(j\) 个还未关闭的区间的方案数(这里未关闭的意思是尚未肯定区间的右端点)。显然考虑每个还未关闭的区间,都会给当前点加上 \(1\) ,据此能够推出状态转移方程了。时间复杂度 \(O(n)\)。
- Sereja and Intervals \(dp[i][j][k]\) 表示到第 \(i\) 个数时,还有 \(j\) 个未关闭的区间,已经关闭了 \(k\) 个区间的方案数。对于每一个数,考虑是关闭前面的区间呢(显然只能关闭第一个未关闭的区间)?仍是新开一个区间?仍是无论这个数。
- Ducks in a Row 能够发现翻转的区间必定不相交,因此能够考虑 \(DP\)。\(dp[o][i][j][k]\) 表示到 \(o\) 这个位置,前面是否翻转 ( \(i\) ),连续的 \(D\) 的数量为 \(j\) ,符合条件的\(D\)连续段的数量为 \(k\) 时所需的最小翻转次数。由于 \(j*k\leq\)字符串的长度。因此时间复杂度 \(O(n^2)\)。
- Spinning Up Palindromes \(dp[l][r][i][j]\) 表示 \(S[1...l]\) 等于 \(S[r...n]\) 时从 \(dp[l-1][r+1][i'][j']\) 转移过来,\(l+1\) 是否须要向 \(l\) 进位 (\(i\)) ,\(r\) 从 \(r+1\) 获得的进位为 \(j\) 时的最小花费。转移怎么好写怎么来,大力枚举使得两边相同时要加的数便可。由于 \(l\) 和 \(r\) 具备相关性,因此数组能够写成 \(dp[l][i][j]\)。
- Eighty seven 考虑前缀后缀,开两个 \(bitset\) 类型的 \(DP\) 数组,之前缀为例,\(dp[i][j][k]\) 表示到第 \(i\) 个数,必定不选 \(j\) 这个位置上的数,选了 \(k\) 个数时全部可能的和(二进制位为\(1\)表示有这样的和)。对于后缀的数组,若是二进制位 \(i\) 上的数字为\(1\),可修改成 \(bit[87-i]=1\),那么对于询问,枚举 \(k\) ,将前缀后缀按位与,检查是否有二进制位为\(1\)。
- Candy Chain \(f[l][r]\) 表示删掉 \(S[l...r]\) 这个子串能获得的最多的钱。而后 \(dp[i] = max(dp[i-1], dp[j] + f[j+1][i]) (j < i)\) ,\(dp[len(S)]\) 即为答案。预处理 \(f[l][r]\),枚举 \(S\) 的子串 \(s\) 以及全部的待匹配串 \(t\) ,令 \(g[i][j]\) 表示 \(s[1...i]\) 删除一些字符(或不删)等于 \(t[1..j]\) 时获得的最多的钱。\(f[l][r]=g[r][len(t)]\)。也能够用字典树优化,将待匹配串建树,一样枚举子串,而后有 \(g[i][j]\) 表示以 \(i\) 结尾的字符串在字典树上的状态为 \(j\) 时能够获得的最多的钱,\(f[l][r]=g[r][0]\)。有三种转移,要么在字典树上向下走,要么删掉一个区间(能够借助已经计算出的 \(f[l][r]\) 转移),要么删掉 \(j\) 这个状态表明的字符串。
- Mahmoud and Ehab and yet another xor task 考虑异或集合的性质(对于任意两个数,他们的异或值都在集合中),对于一个数 \(a[i]\) 若是 \(a[i]\) 不在集合中,那么对于集合中的任意数 \(x\), \(a[i]\ xor\ x\) 都不会在集和中。维护一个集合,枚举 \(a[i]\) ,若是发现 \(a[i]\) 已经在集合中,全部数的构成方案数都翻倍,不然把这个数和集合中全部的数分别异或并加入集合。能够发现这样须要离线处理,另外一种作法,经过预处理线性基在线回答询问。
- Compute Power 求最小比率,二分答案 \(x\) ,若存在更优的答案,则有 \(\sum\frac{a_i}{b_i}<x\),判断是否存在 \(\sum{a_i}-x*{b_i}<0\)。先把给的东西按 \(a\) 从大到小排序,考虑 \(dp[i][j][k]\) 表示到第 \(i\) 个时,等于 \(a[i]\) 的数量为 \(j\) ,大于的数量为 \(k\),根据是否选择进行转移。
树形DP
状态压缩DP
- Little Pony and Harmony Chest 状态中0/1表示是否存在某个素数,最多只有17个素因子。
- Remembering Strings 一维数组,时间复杂度\(O(m2^n)\)。状态中0/1表示某个单词是否变成好记的单词了。
- Another Sith Tournament \(dp[i][S]\) 表示擂主为 \(i\) 时,活着的人状态为 \(S\) 时主角能获胜的几率,\(dp[0][1]=1\)。时间复杂度\(O(n^22^n)\)。
- Exciting Finish! 注意到题目求的是有多少种不一样的排名,即分数不一样排名相同属于同一种状况。又分配的分数呈不降低,因此当咱们分配一个分数给某人时,能够当成也给其余未分配的人分配了相同的分数,那么要使一我的的分数变成最大,只须要比较初始分数便可。\(dp[s][i][j]\) 表示人的状态为 \(s\) ,上一次分配的人是 \(i\),还剩下分数 \(j\) 未分配的方案数。记忆化搜索实现。
欢迎关注本站公众号,获取更多信息