题目分析
这类题型是我们平时所常见的,粗看题目可能会觉得很像背包问题,但是感觉状态转移方程又不是那么容易就可以推出。其实,我们可以把M当作为背包的容量,N个正数对应的数组value[n]既当作其价值,又当作其重量。此时的状态转移方程如下:
当n >= 1, m < value[n-1]时:
F(n,m)=F(n−1,m)
F(n,m) = F(n-1, m)
F(n,m)=F(n−1,m)
当n >= 1, m >= value[n-1]时:
F(n,m)=max(F(n−1,m),F(n−1,m−value[n−1])+value[n−1])
F(n,m) = max(F(n-1,m),F(n-1,m-value[n-1])+value[n-1])
F(n,m)=max(F(n−1,m),F(n−1,m−value[n−1])+value[n−1])
上式中前一个value[n-1]表示重量,后一个value[n-1]表示其价值。
代码实现(java)
有了状态转移方程后,我们便可以使用递归或者自底向上求解,此处我使用自底向上求解,并只使用一维数组记录中间值的方式。具体代码如下:
private static int getNearestSum(int m, int[] value) {
int[] result = new int[m+1];
for (int i = 1; i <= value.length; i++) {
for (int j = m; j >= 1; j--) {
if (j >= value[i-1]) {
result[j] = Math.max(result[j], result[j-value[i-1]] + value[i-1]);
}
}
}
return result[m];
}
本文深入解析了如何将背包问题转化为动态规划问题,通过详细的状态转移方程推导,介绍了如何利用一维数组进行自底向上的求解,提供了一个Java实现的示例代码。

被折叠的 条评论
为什么被折叠?



