4.物品可以分割的背包(Fractional Knapsack)問題 Solution


貪婪準則是先計算所有物品的單位重量的價值,將所有物品以單位重量的價值由大到小進行排序,取最大的單位重量的價值物品開始,若可以放進背包就放入背包,一直到最後放不下為止或所有物品都已經放入,最後放不下的部分取剩餘未放入物品的最高單位重量的價值物品,取其中一部分到背包重量的上限為止,到此求得背包的負重能力範圍內的放入背包所有物品的最大價值。

#include<iostream>
#include<algorithm>
using namespace std;
struct Obj{
  int w; //weight 重量
  int v; //value  價值
  double vw;
};

//CP值最高的放前面
bool cmp(Obj a,Obj b){
  return (a.vw>b.vw);
}
int main(){

  int n,k,tempK;
  double totalValue;//總價值,也就是答案
  Obj obj[101];

  while(cin>>n){

    //輸入每個物品的重量與價值,計算出這個物品的CP值
    for(int i=0;i<n;i++){
      cin >> obj[i].w >> obj[i].v;
      obj[i].vw=(double)obj[i].v/obj[i].w; //價值÷重量=CP值
    }

    cin >> k; //k代表背包負重
    tempK=k;  //暫存負重

    sort(obj,obj+n,cmp);//CP值最高的放前面

    for(int i=0;i<n;i++){
      if (obj[i].w<=tempK) {//如果還沒超重,把物品放進包包
        totalValue+=obj[i].v;
        tempK-=obj[i].w;     //背包容量變少
      }else{
        //目前的物品無法直接放進包包
        //計算如果將物品切下來放進包包
        totalValue+=(double)obj[i].vw*tempK;
        break;
      }
    }
    cout << totalValue << endl;

  }
}

results matching ""

    No results matching ""