#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int curval;
int curcap;
int maxval;
int bagcap;
char *ans;
char *maxans;
int n;
//每件物品的属性
typedef struct object {
int n;
int val;
int cap;
}object;
object *objects;
int comp(const void *_a, const void *_b) {
object a = *(object *)_a;
object b = *(object *)_b;
double x = (double)a.val / a.cap;
double y = (double)b.val / b.cap;
if (y > x) {
return 1;
} else {
return -1;
}
}
//算出如果选择当前的物品所能获得的最大价值
double bound(int cur) {
int tempcap = curcap;
double tempval = curval;
while (cur < n && tempcap + objects[cur].cap < bagcap) {
tempcap += objects[cur].cap;
tempval += objects[cur].val;
++cur;
}
if (cur < n) {
tempval += (bagcap - tempcap) * ((double)objects[cur].val / objects[cur].cap);
}
return tempval;
}
//回溯依次做选择再利用bound函数做剪枝操作
void dfs(int cur) {
if (cur >= n) {
if (curval > maxval) {
strcpy(maxans, ans);
maxval = curval;
}
return;
}
if (objects[cur].cap + curcap > bagcap) {
if (curval > maxval) {
strcpy(maxans, ans);
maxval = curval;
}
dfs(cur + 1);
return;
}
if (bound(cur) > maxval) {
curval += objects[cur].val;
curcap += objects[cur].cap;
ans[objects[cur].n - 1] = '1';
dfs(cur + 1);
curval -= objects[cur].val;
curcap -= objects[cur].cap;
}
ans[objects[cur].n - 1] = '0';
dfs(cur + 1);
}
//输出所做的选择
void show() {
printf("\n");
for (int i = 0; i < strlen(maxans); ++i) {
if (maxans[i] == '1') {
printf("选择了第%d件物品\n", i + 1);
}
}
printf("所获得的最大价值为%d", maxval);
}
int main() {
curval = 0;
curcap = 0;
maxval = 0;
printf("请输入数量");
scanf("%d", &n);
objects = (object*)malloc(sizeof(object) * n);
ans = (char*)malloc(sizeof(char) * (n + 1));
maxans = (char*)malloc(sizeof(char) * (n + 1));
memset(ans, '0', sizeof(ans));
memset(maxans, '0', sizeof(maxans));
ans[n] = '\0';
maxans[n] = '\0';
for (int i = 0; i < n; ++i) {
objects[i].n = i + 1;
printf("请输入第%d件物品的价值", i + 1);
scanf("%d", &objects[i].val);
printf("请输入第%d件物品的容量", i + 1);
scanf("%d", &objects[i].cap);
}
printf("请输入背包的容量");
scanf("%d", &bagcap);
qsort(objects, n, sizeof(object), comp);
dfs(0);
show();
return 0;
}
回溯0-1背包
最新推荐文章于 2024-12-14 00:08:14 发布