public double knapsack(double[] pp,double[] ww,double cc){ //初始化 c=cc; n=pp.length-1; cw=0; cp=0; bestp=0; x=new int[n+1]; bestx=new int[n+1]; //q为单位重量价值数组 q=new Element[n+1]; for(int i=0;i<=n;i++){ q[i]=new Element(i,pp[i]/ww[i]); } //将个物品依单位重量价值从大到小排列 java.util.Arrays.sort(q); //MergeSort.mergeSort(q); p=new double[n+1]; w=new double[n+1]; for(int i=1;i<=n;i++){ p[i]=pp[q[i].id]; w[i]=ww[q[i].id]; } backtrack(1); return bestp; } public void backtrack(int i){ if(i>n){//到达叶子节点 bestp=cp; for(int j=1;j<=n;j++){//保存最优值对应的包的编号 bestx[j]=x[j]; } return; } if(cw+w[i]<=c){//左子树 x[i]=1; cw+=w[i]; cp+=p[i]; backtrack(i+1); cw-=w[i];//恢复现场 cp-=p[i]; } if(bound(i+1)>bestp){ x[i]=0; backtrack(i+1); } } public double bound(int i){//上界函数 double cleft=c-cw;
时间: 2024-01-23 16:03:44 浏览: 51
你的代码是用来解决背包问题的,其中的 bound 函数是用来计算当前节点的上界值。它首先将剩余容量 cleft 初始化为背包剩余容量,然后计算从当前节点到叶子节点所能够获得的最大价值 bound,其中,价值包括已经放进去的物品价值和剩下的物品按单位重量价值排名后取前缀所能够获得的价值。这个函数的返回值就是上界值 bound。
相关问题
运用贪心算法,每次挑选目前单价最高且重量未超过背包剩余容量的物品。补全以下代码#include <iostream.h> #include <stdio.h> typedef struct { char name[16]; // 名称 double p; // 价值 double w; // 重量 double r; // 单价 }good; int main() { int n, i, j, k; good *G, temp; double C; // 存储当前背包容量 double value; // 背包当前所装物品总价 freopen("Knapsack.in", "r", stdin); freopen("Knapsack.out", "w", stdout); cin>>n; cin>>C; G = new good[n]; for(i=0; i<n; i++) { cin>>G[i].name; cin>>G[i].p; cin>>G[i].w; G[i].r=G[i].p/G[i].w; } //************************************************ //================================================= cout<<"Total price: "<<((int)(100*value+0.5))*0.01<<endl; return 0; }
补全的代码如下:
```c++
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef struct {
char name[16]; // 名称
double p; // 价值
double w; // 重量
double r; // 单价
} good;
// 比较函数,用于排序
bool cmp(good a, good b) {
return a.r > b.r;
}
int main() {
int n, i, j, k;
good *G, temp;
double C; // 存储当前背包容量
double value = 0; // 背包当前所装物品总价
freopen("Knapsack.in", "r", stdin);
freopen("Knapsack.out", "w", stdout);
cin >> n;
cin >> C;
G = new good[n];
for(i = 0; i < n; i++) {
cin >> G[i].name;
cin >> G[i].p;
cin >> G[i].w;
G[i].r = G[i].p / G[i].w;
}
// 按照单价从高到低排序
sort(G, G + n, cmp);
// 按照贪心算法选择物品
for(i = 0; i < n; i++) {
if(G[i].w <= C) { // 若当前物品可以放入背包
C -= G[i].w; // 更新背包容量
value += G[i].p; // 更新背包所装物品总价
} else { // 若当前物品无法放入背包
value += G[i].r * C; // 将背包剩余容量全部用于装当前物品
break;
}
}
// 输出结果
cout << "Total price: " << ((int)(100 * value + 0.5)) * 0.01 << endl;
return 0;
}
```
代码中使用了 `sort` 函数进行排序,需要添加头文件 `algorithm`。在选择物品时,如果当前物品无法放入背包,则将背包剩余容量全部用于装当前物品,这是贪心算法的核心思想之一。最后输出结果时,使用了四舍五入的方法,即将数值乘以 100 后加上 0.5,再取整数部分,最后除以 100。
求这串代码的时间复杂度:#include <iostream> #include <algorithm> using namespace std; struct Item { int w; // 物品重量 int v; // 物品价值 double p; // 物品单位重量价值 }; bool cmp(Item a, Item b) { return a.p > b.p; } void knapsack(Item A[], int n, int W) { sort(A, A + n, cmp); // 按照单位重量价值从大到小排序 int i = 0; double V = 0; // 背包中物品的总价值 while (W > 0 && i < n) { // 背包还有剩余空间,并且还有物品可以放入 if (A[i].w <= W) { // 物品可以完全放入背包中 V += A[i].v; W -= A[i].w; } else { // 物品只能部分放入背包中 V += A[i].v * (double)W / A[i].w; W = 0; } i++; } cout << "背包装入的总价值为:" << V << endl; } int main() { int n = 5; // 物品数量 int W = 100; // 背包容量 Item A[n] = {{10, 20, 0}, {20, 30, 0}, {30, 66, 0}, {40, 40, 0}, {50, 60, 0}}; // 初始化物品重量和价值 for (int i = 0; i < n; i++) { A[i].p = (double)A[i].v / A[i].w; // 计算物品单位重量价值 } knapsack(A, n, W); // 求解背包问题 return 0; }
该代码的时间复杂度为 O(nlogn),其中 n 为物品数量。
主要涉及到排序算法的时间复杂度。在该代码中,使用了 STL 中的 sort() 函数对物品按照单位重量价值从大到小进行排序,sort() 函数的平均时间复杂度为 O(nlogn)。除此之外,代码中只有一个 while 循环,时间复杂度为 O(n)。因此,该代码的总时间复杂度为 O(nlogn)。
阅读全文