最近学习动态规划,在背包问题处被卡了很久,故在此处把这几天的遇到的问题和自己的理解进行一下总结。
这篇博文主要介绍的是完全背包的思想,包括它的三种状态转移方程。作为引入完全背包问题的前提,附带的介绍了DAG思想和01背包问题。
参考资料有《算法竞赛入门经典》和《背包九讲》。
1.在《算法竞赛入门经典》中,其对完全背包问题是通过DAG的思想来讨论的。先讨论了完全背包问题,再推广到01背包问题。
2.在《背包九讲》中,讨论顺序相反,其对完全背包的讨论是通过01背包的思想推广而来。
一、先来理解《算法竞赛入门经典》的思想。
在看完全背包问题时先来看一个硬币问题。描述如下:
有n中硬币,每种硬币的面值为v1,v1......vn.且每种硬币有无限多。现在给定一个非负整数S,可以选用多少个硬币,使得面值之和恰好为S。输出硬币数目的最小值和最大值。
分析:如何通过建图求解
把要凑足的总面值看成一个个点。起点为S,终点为0.
那么什么样的两个点是联通的呢?很显然点i到点i-vj(i>=vi)是联通的。取硬币j,状态就由i转移到了i-vj,点i与i-vj联通说面这两点之间有一条线。
很显然,从点i出发的线可能是0条,也可能不止一条。
我们现在的问题就变成了从点S到点0,最长的路径和最短的路径。
定义的d[i]为面值之和为i时最大的硬币数目。则有:
d[i] = max(d[i-v[j]]+1) j : 0->n 且 i-v[j]>=0
这个方