选些最近做的题目写写。
选择物品
动态规划
题意:有 N 种物品,每种有 a(i) 件,问有多少种不同的取法?例如,AB 和 BB 是两种不同的取法。
初步解法:搜索,对于每一件物品,枚举取 0、1、2、...、a(i) 件时的情况,在弱数据下可以拿 80% 的分数。
正解:从上面的搜索思路其实就能找到动规方法了。用 f(i, j) 表示在前 i 种物品中取 j 件的方案数,则
f(i, j) = sum{ f(i-1, j-k), 0<=k<=a(i) }
其实就是对于物品 i 枚举其取 0、1、2、...、a(i) 件时的情况。由此可见恰当划分子问题就能将纯粹的搜索巧妙转化为有大量重叠子问题的动态规划。
进一步:(来自http://www.cnblogs.com/vb4896/p/3927938.html)
由于每次状态转移时都要进行求和操作,所以可以用前缀和来优化。
记 s(i, j) = sum{ f(i-1, 0)+f(i-1, 1)+...+f(i-1, j) },则
f(i, j) = s(i-1, j) a(i)>=j
或 f(i, j) = s(i-1, j)-s(i-1, j-a(i)-1) a(i)<j
这样状态转移的复杂度就变成了 O(1).
旅行优惠
动态规划
题意:将路径的权值定义为路径上边权之和减去最大边权,求权值最小的路径。
解法:设 d(i, j) 表示 i 到 j 之间的最短路,f(i, j) 表示 i 到 j 之间的最小路径权值。d(i, j) 可以用 Floyd 算法在 O(N3) 的时间内求出。而对于 f(i, j),
f(i, j) = min{ f(i, k)+d(k, j), d(i, k)+f(k, j) }, 1<=n<=k
初始条件 f(i, j) = 0, (i, j)∈E
(n 表示顶点数)
这个方程的意思是:枚举中间点 k,那么既然我们要删去一条边的权值,删去的边要么在 i->k 的路径中,要么在 k->j 的路径中。
标程的算法是,先求出任意两点之间的最短路,然后枚举删哪条边,然后再求最短路。这两种方法本质上是一样的。