背包问题
问题描述
假设有一个能装入总体积为T的背包和n件体积分别为w1,w2,…wn的物品,能否从n件物品中挑选若干件恰好装满背包,即使w1+w2+…+wm=T,要求找出所有满足上述条件的解。
例如:当T=10,各件物品的体积{1,8,4,3,5,2}时,可找到下列4组解:
(1,4,3,2)
(1,4,5)
(8,2)
(3,5,2)。
实现提示
可利用回溯法的设计思想来解决背包问题。首先,将物品排成一列,然后,顺序选取物品装入背包,若已选取第i件物品后未满,则继续选取第i+1件,若该件物品“太大”不能装入,则弃之,继续选取下一件,直至背包装满为止。如果在剩余的物品中找不到合适的物品以填满背包,则说明“刚刚”装入的物品“不合适”,应将它取出“弃之一边”,继续再从“它之后”的物品中选取,如此重复,直到求得满足条件的解,或者无解。由于回溯求解的规则是“后进先出”,自然要用到“栈”。
交互界面
算法思路
背包问题
void myPackageProblem::PackagePSolve()
{
int Stack[10] = { 0 };
int answer[10][10]={ 0 }, answernumber = 0;
int rear = 0, front = 0, volume = 0;
int i=0;
static int record=0;
while (front < itemNum)
{
Stack[rear] = VolumeArray[i];
volume = volume + Stack[rear];
rear++;
if (volume < maxvolume)
{
record = i;
}
else if (volume >maxvolume)
{
volume = volume - Stack[rear-1];
Stack[rear - 1] = 0;
rear--;
}
else if (volume == maxvolume)
{
int k = 0;
for (int m = front; m < rear; m++)
{
answer[answernumber][k] = Stack[m];
ui->textEdit->moveCursor(QTextCursor::End);
ui->textEdit->insertPlainText(QString::number(Stack[m]));
ui->textEdit->insertPlainText(" ");
}
ui->textEdit->append("");
answernumber++;
volume = volume - Stack[rear-1];
Stack[rear - 1] = 0;
rear--;
}
if (i == itemNum-1)
{
i = record+1;
volume = volume - Stack[rear-1];
Stack[rear - 1] = 0;
rear--;
}
else
{
i++;
}
if(record==itemNum-1)
{
for(int l=front;l<rear;l++)
{
Stack[l]=0;
}
volume = 0;
front++;
rear=front;
record=front;
i=record;
}
}
if(answernumber==0)
{
ui->textEdit->insertPlainText("没有适合的解");
}
}