动态规划如何选取一维数组还是二维数组
总结:
* 当题目种涉及到两个变量时需要借助二维数组来实现动态规划,例如 背包问题中,涉及容量和重量两个变量,则需要两个维度来考虑
* 当题目中只有一个变量时,使用一维数组解决动态规划问题,例如相隔数据和最大,变的只是数据的和,因此只设置一个一维数组用于存放数据和即可
举例:
背包问题:使用二维数组,将每次的结果保存于二维数组中,求解的下一个结果依赖于上次已经求好的结果,最终结果就在二维数组的右下角
private static int dp_OPT(int n, int v) {// n为当前物品,v为当前剩余容量
int[][] result = new int[weight.length][v + 1];
// 创造一个二维数组,用于存放各种情况对应的最优解,行数表示保存第几个物品,列数保存背包容量
// 二维数组的第0行0列都是0,故二维数组的列数应该为v+1(weight数组已经将第一个元素设置为0)
// 二维数组的行数 = 数组名.length,列数=数组名[0].length;
for (int i = 0; i < result[0].length; i++) {
result[0][i] = 0;
}
for (int i = 0; i < result.length; i++) {
result[i][0] = 0;
}
for (int i = 1; i < result.length; i++) {
for (int j = 1; j < result[0].length; j++) {
// j >= weight[i] 当前容量是否可以放下物品i
// 当能容下物品i时,如果选i : value[i] + result[i-1][j-weight[i]] 即当前物品i的价值+前i-1个物品的最大价值
//当容量不足以装下i时,则最大价值为前i-1个物品的最大价值,即result[i-1][j].
result[i][j] = j >= weight[i] ? Math.max(value[i] + result[i - 1][j - weight[i]], result[i - 1][j])
: result[i - 1][j];
}
}
return result[n][v];
}
求相隔数据最大数据和
private static int dp_OPT(int[] data,int i) {
int [] opt = new int[data.length]; //借助一维数组存放最优解
int A,B;
opt[0] = data[0];
opt[1] = Math.max(data[0], data[1]);//排除特殊情况
for (int j = 2; j < data.length; j++) {
A = opt[j-2] + data[j];//选J
B = opt[j-1];//不选J
opt[j] = Math.max(A, B);
}
return opt[i];
}
注意
关于动态规划问题有两种实现方法,一种是递归解决,另一种是非递归解决,递归解决往往时间复杂度较高,非递归解决则是采用空间换时间的策略。
对于递归式解法:数据从后向前,假设最大数据为n ,则依次计算n-1,n-2,…,1
非递归式采用的辅助变量(一维数组或二维数组)则是从前向后,假设最大数据为n ,则依次为1,2,3,…,n,辅助变量的最后一个值便为最终答案。