問題描述
思路
回溯法求解,解空間是一棵子集樹。
算法的時間複雜度爲O(2n)
代碼
#include <iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include<math.h>
int bestv=0;//存放最優值
int cv=0;//當前揹包的價值量
int cw=0;//當前揹包的重量
int v[101];//存放物品價值量數組
int w[101];//存放物品重量數組
int x[101];//存放當前解
int bestx[101];//存放最優解
//回溯法 解空間是一個二叉樹 遞歸回溯
void getbestv(int i,int n,int c)
{
if(i>n){//遞歸出口,到了葉子節點以後了
//如果當前揹包價值量cv大於最優值bestv,更新最優值,最優解
if(cv>bestv){
bestv=cv;
for(int k=1;k<=n;k++)//更新最優解
bestx[k]=x[k];
}
return ;//遞歸出口
}
//子集樹,j=0或者j=1兩種條件求解
for(int j=0;j<=1;j++){
x[i]=j;//x[i]=0,x[i]=1兩種情況都遍歷
if(cw+w[i]<=c){
//更新當前揹包重量,當前揹包價值
cw=cw+x[i]*w[i];
cv=cv+x[i]*v[i];
//子集樹向下尋找
getbestv(i+1,n,c);
//還原揹包重量,揹包價值
cw=cw-x[i]*w[i];
cv=cv-x[i]*v[i];
}
}
return ;
}
int main()
{
int c;//表示揹包的容量
cin>>c;
int n;//表示有n個物品
cin>>n;
for(int i=1;i<=n;i++)
cin>>w[i];
for(int i=1;i<=n;i++)
cin>>v[i];
getbestv(1,n,c);
cout<<bestv;//輸出最優值
}