Bone Collector-0-1背包
update@2011-08-05
memset(dp[0],0,sizeof(int)*(v+1));//不放任何物体不管背包容量多少 价值都是0
for(i = 1;i <= n;i++){
//处理第i 个物体,在当前背包容量为j的时候选还是不选这个物体
for(j = 0;j <= v;j++){//枚举每个容量
if(bone_volume[i] > j){//这个物体肯定是不能放在容量为j的背包里的
//不知道为什么有些解题报告没有这个判断(大部分是有的)
//如果j < bone_volume[i],相减之后就小于0了
dp[i][j] = dp[i-1][j];
}
else{//如果体积刚好等于剩余的容量也不一定会被放进去
//因为可能有其它几个物体组合之后的价值比这个单个物体的高
dp[i][j] = mymax(dp[i-1][j],dp[i-1][j-bone_volume[i]]+bone_weight[i]);
}
}
}//结果保存在 dp[n][v]中,即对前n个物体做出取舍后的最优解
HDU -Bone Collector
都说它很水,我却搞了半天 = =.不是状态方程什么的,说到底是没明白dp的思想
01背包是背包中最基础的。之前一直不能理解的是 i=1的时候怎么做取舍,选第一个还是不选第一个?
- i=1的时候,我们枚举了每个剩余容量(即dp[1][j])的最优解,到底全局最优解最终取哪个剩余容量还不知道,注意每个剩余容量对应着一个i的状态 即取i和不取i ,比如剩余容量为0的时候肯定是不取i物体的
- i =2时也要枚举出每个剩余容量的最优解,对于这个子结构来说,此时我们才知道第一个物体选了还是没选,而对于全局最优解来说仍然是不知道的 因为不知道最终会选择哪个最优子结构(所以才叫局部最优嘛)
- 如果i = n(最后一个物体了)此时就是全局最优(也可以叫局部最优)
- 我觉得关键是在剩余容量,每个物体都对应着v种剩余容量(不一定是v种 有些不会出现 这里姑且就这么说)在构造最优解的时候对剩余容量作取舍即对该物体选还是不选作了取舍。
- 复杂度比枚举低是因为枚举时第i个物体和第i-1个物体的取舍没有关系 所以乘以2;dp的方法, 第i个物体的取舍依赖于第i-1,只需比较一次, O(1)
- 这里不讨论优化到一维的,主要是理解算法