贪心法——最优装载问题
问题:
有一批集装箱要装上一艘载重量为c的轮船。其中集装箱i的重量为wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
0-1背包在价值相同时的特例。
分析:
直管思路:先装最轻的。
将所有物品从轻到重排序。
贪心选择:选择第一个待选物品。
父问题:给出待选物品的一个最优选择。子问题:给出选了第一个待选物品后的最优选择。
贪心选择性质证明:利用数学归纳法,证明两点:1.原问题以贪心选择开始,也就是证明数学归纳法的归纳基础成立;2.对于任意规模的以贪心选择开始的问题,若其取最优解,那么贪心选择之后生成的子问题仍然具有以贪心选择开始的最优解,也就是证明数学归纳法的归纳步骤成立。
- 若要装尽可能多的集装箱,那么一定要装第一个(最轻的货物),否则最轻的货物替换掉选中的某个货物一定能得到更优的解。
- 对于剩下的一部分集装箱,同理还是要选最轻的,选中这个最轻的后,剩下的所有货物还是要选最轻的(这一点就是最优子结构性质)
最优子结构性质:剩下的一部分集装箱,选择最轻的使得其得到最优解,剩下的货物中选出的最优解加上这个货物就是父问题的最优解。
代码:
// 最优装载问题
// 输入:物品数量n,最大载重c,物品重量序列w,是否选择某物品x
void Loading(int n,float c,float w[],int x[]){
sort(w,w+n);
for(int i = 0;i < n;i++){
if(c>=w[i]){
x[i] = 1;
c -= w[i];
}else{
x[i] = 0;
}
}
}
复杂度:
时间复杂度:排序O(nlogn)+迭代O(n)
空间复杂度:O(n)
一些思考:
贪心选择性质侧重贪心选择可以得到一个局部的最优解,重点在于递推
最优子结构性质侧重每个局部最优解都是由每一步的贪心选择组成的,重点在于组合
目前认为贪心是一种特殊的较为简单的动态规划递推式