描述:
這里有n種不同值v[i]和權重w[i]的對象(如果選擇該對象的w[i]可以獲得值v[i])。
你有一個容器來挑選它們。你可以根據自己的需要把它們分成任意大小的碎片。可以拾取的對象的最大重量給定為w。請計算您能得到的最大值。
輸入:
第一行輸入n W(0<=n<=1000)(0<=W<=10000)
第二行輸入n個物品的價值(0<=v[i]<=10000)
第三行輸入n個物品的質量(0<=w[i]<=10000)
輸出:
最大的價值,保留三位小數。
分析:
本題跟傳統的0-1背包問題不同,本題中的物體可以分成任意份,所以我們可以運用貪心算法,根據物品的性價比(價值 / 質量)來解題,根據性價比的高低依次將物體放入背包中,當物體不能完全放入背包時,總價值 = 完全放入物品的價值 + 背包剩余空間 * 接下來應放入背包物品的性價比。
代碼:
#include <iostream> #include <algorithm> #include<iomanip> using namespace std; //需要一個結構體,通過性價比,能夠查找到重量和價值。 //做一個排序,需要將性價比由高到底排序,排序的過程中重量和(價值)要對應上 typedef struct { double aver; double w; double v; }Knapsack; bool cmp(Knapsack a, Knapsack b) { return a.aver > b.aver; } int main() { Knapsack arrays[1009]; int n; double m; double V = 0; cin >> n >> m; for (int i = 0; i < n; i++) cin >> arrays[i].v; for (int i = 0; i < n; i++) cin >> arrays[i].w; //求性價比 for (int i = 0; i < n; i++) { arrays[i].aver = arrays[i].v / arrays[i].w; //cout << arrays[i].aver << endl; } //性價比排序 sort(arrays, arrays + n, cmp); int sum = 0; for (int i = 0; i < n; i++) //當背包能裝下所有物品時,直接輸出所有的物品價值之和 { sum += arrays[i].w; } if (sum < m) { for (int j = 0; j < n; j++) V += arrays[j].v; //V = floor(V * 1000.0) / 1000.0; cout << setiosflags(ios::fixed) << setprecision(3) << V << endl; return 0; } //應該由性價比的順序,通過容量,選擇裝入的物品 for (int i = 0; i < n; i++) { if (arrays[i].w <= m) { V = V + arrays[i].v; m = m - arrays[i].w; } else {//直接將剩余的m加入即可 V = V + m * arrays[i].aver; m = 0; } if (m == 0) break; } //V = floor(V * 1000.0) / 1000.0; cout << setiosflags(ios::fixed) << setprecision(3) << V << endl; return 0; }