背包dp很简单啊
用二维数组的方式去思考
用一维数组的方式去优化
这里不再赘述了
但是我碰到一道来自华为的笔试题
发现需要把最优情况下的序号都输出出来
这就让我难办了
当时我建立在一维的优化后的情况去思考
导致怎么都想不出来
后来改回了二维
终于解决了
先看一下普通二维求最优解
int[][] f = new int[n+1][weight+1]; for(int i = 1;i <= n; i ++) { for (int j = 0; j <= weight; j ++) { int index = i - 1; int val = w[index]; if (val > j) { f[i][j]=f[i-1][j]; } else { f[i][j]=Math.max(f[i-1][j], f[i-1][j-val]+v[index]); } } }
其实拿到路径很简单
我们可以用一个int来存储路径
比如100010101
我们只需要把int看成二进制
作左移运算
就可以把路径存进去
作右移运算
就可以把路径取出来
下面是处理好路径后的代码
int[][] f = new int[n+1][weight+1]; int[][] r = new int[n+1][weight+1];//记录 for(int i = 1;i <= n; i ++) { for (int j = 0; j <= weight; j ++) { int index = i - 1; int val = w[index]; if (val > j) { f[i][j]=f[i-1][j]; r[i][j]=r[i-1][j]; } else { f[i][j]=Math.max(f[i-1][j], f[i-1][j-val]+v[index]); if (f[i][j] > f[i-1][j-val]+v[index]) { r[i][j] = r[i-1][j]; } else { r[i][j] = r[i-1][j-val]; r[i][j] += 1 << index; } } } } int p = r[n][weight]; for (int i = 0; i < n; i ++) { int t = (p >> i) % 2; if (t == 1) { System.out.print(i+1); } }
非常的简单
测试用例是
int weight = 5; int n = 4; int[] w = {2,1,3,2}; int[] v = {3,2,4,2};
输出结果是
124
当然也可以优化成一维数组,这个思路我估计是最好的思路了,只需要多开一个同等大小的数组就可以解决问题了
如果还有其他思路
望赐教