zoj 动态规划分类

来源:互联网 发布:软件开发英语词汇 编辑:程序博客网 时间:2024/05/17 04:41

动态规划

 解 #1100 经典,状态压缩 DP,要先枚举出行全部可能的状态,DP[i][j] 表示 i 层,j 末状态,dp[i][st[j][1]]+=dp[i-1][st[j][0]];


#1425 交叉线匹配,经典 DP,n^3。


#1503 估价游戏,一个决策为背景的 DP,当前剩下 i 次机会和 j 条命,最优的策略可以覆盖 DP[i][j] 范围内的所有情况,那么DP[0][j] = 0, DP[i][0] = i, DP[i][j] = DP[i-1][j-1] + 1 + DP[i-1][j]。


#1520 经典背包,记录路径,放得下就行。


#1524 在线刷新,维护一个序列 V[M],表示当前可以买到菜单上某一个物件的最便宜值。


#1558 欧元面值组合,DP,其实本质是 BFS,对于每一个目标价格,做一次 BFS,每次增加一个币。由于是 BFS,得到的最短次数即为所求。值得注意的是,可以先让钱加到一个很大的数,然后再减回来,因此 DP 数组要开大一点。


#1563 珠宝采购,类似背包,n^3 的 DP,DP[k] 为买完第 k 种珠宝之后的最小花费。然后,对于每个 k,可以考虑用它代替前面的 j..k 种珠宝,然后选择不同的 j 以更新最小值,即可完成 DP。


 #1883 简单 DP,明显长度为 n,最大数字是 k 的串有 (k+1)^n 个。那么只需求出 tight 的有多少个就行,这样的话就可以 DP 了。#1738 比较简单的 DP, DP[k][x] 表示 x 在累加 k 次之后有多少种选择,然后类似背包加入即可。#1792 类似 LCS 的经典 DP,O(n^3),基因串匹配,1027 的升级版。#1986 信号线连接,经典 LIS,必须用 O(nlogn) 的算法,否则超时。


#1991 先作图处理,dfs 求二分图连通块,然后可以 DP,具体细节见解题报告。


#2059 双塔,超经典 DP,每加入一个高度,更新双塔高度差为 i 时较低塔高度的最大值 DP[i]。


#2061 买票,经典组合数学 DP,先用类似于求组合数的手法 DP 出不区分的种类数。然后将结果乘以 M! * N! 即可得到全排列数,记得用大数。


#2068 DP,关键在于,排序之后最优的解匹配中必定不存在交叉。


#2136 经典,O(n^2) 的 LIS。#2156 非常经典的多重背包问题,具体算法可见背包九讲。注意物品拆分,路径保存和最优性判断。


#2189 多重背包问题,与 2156 基本一样。但规模较少,直接用最原始的拆分即可。


#2202 不难的 1 维 DP,O(n)但是下面的一种情况绝对不能忽略!因为 0 是没有编码的!


#2224 典型可重复选取背包,数值较大,用 map 不失为好的实现。10 个物品也顶多是出来 2<<10 大约 1000 个价格组合。#2271 碰到女孩的概率,入门级概率 DP,每过一天更新一下 girl 在各个格子的概率,然后将遇上的格子的概率累加并清空,最后累加结果就是最终结果。


#2297 拳皇,状态压缩 DP,将 n! 的状态压缩到 2^n,假设用二进制位 bit 表示哪些人已经打过 DP[bit] 表示打过这些人之后剩下的最大血量,即可进行 DP,从打了 k 个人推到打了 k+1 个人,因此只需 DP 2^n * n 的效率,对于 n <= 20,小菜一碟。#2401 经典 DP,字符串合并,跟 LCS 差不多,类似混合水果名字那个题。


#2402 求 1..m 的数字里面取 n 个构成子序列,每一个必须至少是前一个的两倍,求有多少种。DP 选取第 i 个数字的时候,最后一个数字是 j 有多少种情况。#2414 求一个素数是否可分拆成几个其他素数的和,最少能分拆成几个,输入 <= 10000,类似0/1背包地处理一下即可,另外,其实根据哥德巴赫猜想,顶多也只有 3 个。


#2501 简单 DP,最优化取到第 i 个车厢,使用了 j 个机头时最多的乘客数。


#2527 寻找最长的等差子串,先预排序,然后用类似 LCS 的 DP,DP[i][j] (i<j)表示数列最后一段是 A[i], A[j] 的往前有几个,这样往前可以二分查找。


#2771 在线刷新,DP[i][j] 为第 i 次反射,正处于第 j 个状态的路径数,状态 j 由反射层位置及上下方向决定。#2811 圆弧拼接,等价于求一组边(可以只取部分)能不能组成多边形,用 DP,一组边里面组合能形成等价为长度在区间 [low, high] 的边,加进去新的边,对区间只能扩大,不能缩小,直到 low <= 0 即可。


#2822 类似背包的 DP,DP[i][j][k] 表示共 i 个数编号小于 j 总和为 k 的方案数。#2949 求期望的决策次数,非常短小的 DP,DP[M][N] 是两种面剩余碗数时的期望。初值是 DP[0][j] = DP[i][0] = 0。递推条件是 DP[i][j] = 1 + DP[i-1][j] + DP[i][j-1]。


#2972 刘翔,奥运专栏,在线刷新,跨到当前栏,处于各种状态的时候,最优的结果。


#3013 经典 DP,保持某个 text 前缀往前最小的划分花费,注意,每个 passage 都要输出一个值和划分串,另外,字典的存储容易超时,可选用 Trie 或 Hash。


#3017 魔法城堡游戏,BFS 状态,状态由所在城堡、所在楼层以及剩余魔法构成。


#3034 n^2 的 DP,类似于最长公共子串(LCS)。


#3049 先贪心再 DP,对于非魔法物品和鉴定反而价值减少的,直接卖掉,如果卖掉这些之后的钱购买卷轴直接将其它的全部鉴定卖掉,否则要选择一些不鉴定就先卖掉,这样就成 了一个 DP,假设每个剩下的物品都有一个基础价和增值,求一个子集,基础价之和能凑够钱买卷轴并且增值损失最少,是个类似背包的 DP。


#3060 O(n^3) 的 DP,先预处理出每个位置往左和往右回到原位的最大值,然后按层 DP 到达 (i,j) 位置能够达到的最大值。


#3141 掰巧克力,经典,问掰多少下能把 M * N 的巧克力掰成全部是正方型的。用 DP,DP[M][N] 表示 M * N 需要的次数。那么初始条件就是 DP[i][i] = 0。递推条件就是 DP[M][N] = min(DP[i][N] + DP[M-i][N] + 1, DP[M][j] + DP[M][N-j] + 1)。其中 0<i<M,0<j<N。用递归做这个 DP 比较方便。 #3160 给一个序列,某些编号之间如果相邻可以消去,问最多可以消掉多少个。经典 DP,先预处理出从 i 到 j 可以连块消掉的邻接矩阵,然后将这些块串接起来。


#3171 给一个字符串,问里边不同的子序列是 'seven' 的有多少个。很经典很巧妙的 DP 题,O(n) 的时间空间就可以解决。#3211 砍树,经典DP,由于最后按天排序的砍树序列必有 b[i] <= b[j],当 i < j。因此,先对 b[1..N] 排序,然后再用 DP 解决,复杂度 O(N*K)。