2638: 分支限界法-0-1背包问题
金币值:3
定数:9
时间限制:1.000 s
内存限制:128 M
正确:3
提交:4
正确率:75.00% 命题人:
题目描述
给定n种物品和一背包。物品i (1≤i≤n) 的重量是wi (wi > 0),其价值为vi (vi > 0),背包的容量为c (c > 0)。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
测试代码 复制
#include <stdio.h>
// 为了方便编写限界函数,假设按照单位重量获利递增的顺序输入每个物品的重量和获利。
#define MaxSize 100 //最多节点数
int n; //物品数量
int c; //背包容量
int w[MaxSize]; //依次存放各个物品的重量,0号单元不用
int v[MaxSize]; //依次存放各个物品的价值,0号单元不用
int bestx[MaxSize]; //存放程序执行过程中已经找到的当前最优解,0号单元不用
int bestv=0; //存放程序执行过程中已经找到的当前最优值
typedef struct {
int cw; // 当前已放物品的重量
int cv; // 当前已放物品的获利
int i; //当前在解空间树中的层数,假设根结点是第1层
int x[MaxSize]; // 当前解向量
} QNode; //存放解空间树中的节点数据
typedef struct { //存放节点的顺序循环队列
QNode Q[MaxSize];
int front,rear;
} SqQueue;
void InitQueue(SqQueue &sq) { //队列初始化
sq.front=0;
sq.rear=0;
}
int QueueEmpty(SqQueue sq) { //判断队列是否为空
if(sq.front==sq.rear) {
return 1;
} else {
return 0;
}
}
int QueueFull(SqQueue sq) { //判断队列是否为满
if(sq.front==(sq.rear+1)%MaxSize) {
return 1;
} else {
return 0;
}
}
void EnQueue(SqQueue &sq, QNode e) { //入队
if(!QueueFull(sq)) {
sq.Q[sq.rear]=e;
sq.rear=(sq.rear+1)%MaxSize;
} else {
printf("Error:queue is full\n");
}
}
void DeQueue(SqQueue &sq, QNode &e) { //出队
if(!QueueEmpty(sq)) {
e=sq.Q[sq.front];
sq.front=(sq.front+1)%MaxSize;
} else {
printf("Error:queue is empty\n");
}
}
void BB() {
SqQueue sq;
InitQueue(sq);
// 构造根结点
QNode e;
e.cw=0;
e.cv=0;
e.i=1;
EnQueue(sq,e);
while(!QueueEmpty(sq)) {
DeQueue(sq,e);
if(e.i==n+1) {// 处理解空间树中的叶子结点
if(e.cv>=bestv){
bestv=e.cv;
for(int j=1; j<=n; j++) {
bestx[j]=e.x[j];
}
}
} else { // 处理解空间树中的非叶子结点
//处理左孩子,要该物品
QNode le=e;
___________
le.i++; // 准备好进入下一层
if(le.cw<=c) { // 如果满足约束条件
EnQueue(sq,le);
}
//处理右孩子,不要该物品
QNode re=e;
_____________
re.i++; // 准备好进入下一层
EnQueue(sq,re);
}
}
}
int main(void) {
scanf("%d %d",&n,&c);
for(int i=1; i<=n; i++) {
scanf("%d",&w[i]);
}
for(int i=1; i<=n; i++) {
scanf("%d",&v[i]);
}
BB();
printf("%d\n",bestv);
return 0;
}
输入格式
第1行输入两个整数分别表示物品的数量和背包容量。
第2行输入n个整数分别表示每个物品的重量。
第3行输入n个整数分别表示每个物品的获利。
第2行输入n个整数分别表示每个物品的重量。
第3行输入n个整数分别表示每个物品的获利。
输出格式
第1行输出整个背包的最大获利。
输入样例 复制
3 50
45 25 25
28 15 15
输出样例 复制
30