第一篇博客给自己立一个简单的小规矩:
由于水平不足等诸多原因, 每一篇博客可能在之后都会得到相应的修改以补充说得不正确, 不到位, 幼稚的言论, 尽量一题多解(优化完善算法) 每日最少一题(若出现意外, 补上)
我是看罗勇军, 郭卫斌老师的<算法竞赛入门到进阶>学习的DP问题, 我个人觉得讲得还比较透彻, hdu 2602 题文如下:
Problem Description:
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the maximum of the total value the bone collector can get ?
许多年前,在泰迪的家乡,有一个人被称为"骨头收藏家"。这个人喜欢收集各种骨头,例如狗的,牛的,他也去了坟墓。。。
骨收藏家有一个大袋子,卷V,并在他的收集之旅有很多骨头,显然,不同的骨头有不同的价值和不同的体积,现在考虑到每块骨头的价值沿他的行程,你能计算出骨收藏家可以得到的最大的总价值吗?
Input:
The first line contain a integer T , the number of cases.
Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
第一行包含整数 T,案例数。
其次是T例,每例三行,第一行包含两个整数N,V,(N <=1000,V &=1000)表示骨头的数量和他的包的体积。第二行包含代表每个骨骼值的 N 整数。第三行包含代表每个骨骼体积的 N 整数。
Output:
One integer per line representing the maximum of the total value (this number will be less than 231).
每行一整数表示总值的最大值(此数字将小于 231)。
Sample Input:
1
5 10
1 2 3 4 5
5 4 3 2 1
Sample Output:
14
From: Teddy
题解思路:
既然明确是DP问题,就按照DP的思路来解题, 我理解中的DP就是要找到所谓的状态转移方程, 其实也就是前一项和后一项的递推关系, 如果找到了这种递推关系, 那么问题将迎刃而解,多做几道DP之后, 我会再来总结我对DP的心得和体会.
而就本道题而言, 我们可以从一以下思路来考虑: 我们要考虑的问题实际上只有 (1)装几个骨头, (2)特定背包容量能装骨头的最大价值, 我们设想, 如果我们能弄清楚每一种容量的背包能装最大价值的骨头是多少, 我们就可以顺势推出题目给出的样例中骨头的最大价值是多少,而这也恰恰是DP问题的核心思想, 而我们要想推出每一种容量的背包能装骨头的最大价值, 困扰我们的还有一个问题, 那就是一共装几个骨头, 对于一根骨头来说他有两个属性(本题中) :(1)大小 / 重量; (2) 价值 , 在有限空间内使物品的价值最大 , 这是经典的0/1背包问题(也就是装与不装的问题) , 于是我们就有了一种暴力法: 只需要我去遍历每一次装不同的骨头,再用if去判断该方案可行与否最后取最大价值max, 我甚至不需要状态转移方程也可以推出. 但这里要用一种DP的思维, 这道题将更简便易懂.从1开始遍历我想要的骨头数,对于后面的2,3我可以用前面算出来更小的来进行计算优化。