每天坚持做算法题,熟悉基本的套路,巩固语言基础,总结经验记下所学所想。
矩形问题
嵌套矩形问题。有n个矩形,每个矩形可以用两个整数a、b描述,表示它的长和宽。矩
形X(a,b)可以嵌套在矩形Y(c, d)中,当且仅当a<c,b<d,或者b<c,a<d(相当于把矩
形X旋转90°)。例如,(1, 5)可以嵌套在(6, 2)内,但不能嵌套在(3, 4)内。你的任务是选出尽
量多的矩形排成一行,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内。如
果有多解,矩形编号的字典序应尽量小。
HINT
矩形之间的“可嵌套”关系是一个典型的二元关系,二元关系可以用图来建模。如果矩
形X可以嵌套在矩形Y里,就从X到Y连一条有向边。这个有向图是无环的,因为一个矩形无
法直接或间接地嵌套在自己内部。换句话说,它是一个DAG。这样,所要求的便是DAG上
的最长路径。
代码
1 | // 动态规划问题是逆向思考的 |
硬币问题
硬币问题。有n种硬币,面值分别为V1, V2, …, Vn,每种都有无限多。给定非负整数S,
可以选用多少个硬币,使得面值之和恰好为S?输出硬币数目的最小值和最大值。
1≤n≤100,0≤S≤10000,1≤Vi≤S。
HINt
此问题尽管看上去和嵌套矩形问题很不一样,但本题的本质也是DAG上的路径问题。将
每种面值看作一个点,表示“还需要凑足的面值”,则初始状态为S,目标状态为0。若当前在
状态i,每使用一个硬币j,状态便转移到i-Vj。
这个模型和上一题类似,但也有一些明显的不同之处:上题并没有确定路径的起点和终
点(可以把任意矩形放在第一个和最后一个),而本题的起点必须为S,终点必须为0;点固
定之后“最短路”才是有意义的。在上题中,最短序列显然是空(如果不允许空,就是单个矩
形,不管怎样都是平凡的),而本题的最短路却不容易确定。
代码
1 | // 最长路 |