一、部分背包问题算法基本思想
部分背包问题是基于贪心法的基本思想。
何谓贪心法,只要你够贪心,就能领略贪心算法之精髓。
部分背包问题和0/1背包问题的区别就是:部分背包问题中的单个物品,可以取一部分装入背包。而0/1背包问题则是要么全部拿走,要么一无所有(这里引用了LOL卡牌大师的台词)。 那么作为一个so greed的你,肯定应该知道按照什么顺序拿物品的把。没错,看着值钱的先抢! 这里所说的值钱,指的是单位重量所产生的价值越大(即value/weight的比值越大)。那么问题很简单咯~,把"值钱"的东西排在前面,每次拿抢的时候,问问看背包君够不够承受得住,承受的了,就全部抢过来。承受不住,那么只能按照所能承受的重量,取物品的一部分了。当然价值也得按照比例来哦~
二、部分背包问题的数据结构
结构体Good{
int id: 表示物品的id
double w: 表示物品的重量
double v: 表示物品的价值
}
Good goods[i] 一维结构体数组:表示物品i。
三、部分背包问题过程图解
这个问题已经很简单了,所以就不给图解了。
四、算法源代码
// // FractionalKnapsack.cpp // Algorithm // // Created by Mr.Jim on 12/8/14. // Copyright (c) 2014 weef. All rights reserved. // #include <stdio.h> #include <algorithm> using namespace std; //物品结构体,包含两个属性,w表示重量,v表示价值 struct Good{ int id; double w; double v; }; //排序比较函数,以物品的价值/重量比值降序排序 bool cmp(Good a, Good b){ if (a.v/a.w > b.v/b.w) { return true; } return false; } //结构体数组,所有物品信息 struct Good goods[] = {{1,10,12},{2,9,9},{3,11,7},{4,12,9},{5,6,8},{6,3,4}}; //背包总重量 double totalW = 30; int main() { //以物品的价值/重量比值降序排序 sort(goods,goods+6,cmp); double leftW = totalW; int totalV = 0; //遍历排好序的物品数组 for (int i=0; i<6; i++) { //如果当前背包所能承受的重量大于i物品的总量 //那么把i物品全部放进去 if (leftW >= goods[i].w) { leftW -= goods[i].w; totalV += goods[i].v; printf("choose good[id = %d], %.1f weight,make %.1f value\n",goods[i].id,goods[i].w,goods[i].v); //如果不能,那么取当前背包所能承受重量的相应数量物品 //当然价值也得按照比例来 }else { totalV += leftW/goods[i].w * goods[i].v; leftW = 0; printf("choose good[id = %d], %.1f weight,make %.1f value\n",goods[i].id,leftW,leftW/goods[i].w * goods[i].v); break; } } printf("max total value:%d\n",totalV); return 0; }