多个限定条件下的背包问题

非传统01背包问题。而是有多个限定条件,即物品的属性增加。但每种物品还是仅有放或不放两种结果。将原m[][]扩充为3维。


#include

using namespace std;
int max(int x,int y)
{
return x>y?x:y;
}
int min(int x,int y)
{
return x>y?y:x;
}
void Knapsack(int *v,int *w,int c,int *b,int d,int n,int m[][11][11])
{
int jMax=min(w[n]-1,c);
int kMax=min(b[n]-1,d);
for(int j=0;j<=jMax;j++)
for(int k=0;k<=d;k++)
m[n][j][k]=0;
for(int k=0;k<=kMax;k++)
for(int j=0;j<=c;j++)
m[n][j][k]=0;
for(int j=w[n];j<=c;j++)
for(int k=b[n];k<=d;k++)
m[n][j][k]=v[n];
for(int i=n-1;i>1;i--)
{
jMax=min(w[i]-1,c);
kMax=min(b[i]-1,d);
for(int j=0;j<=jMax;j++)
for(int k=0;k<=d;k++)
m[i][j][k]=m[i+1][j][k];
for(int k=0;k<=kMax;k++)
for(int j=0;j<=c;j++)
m[i][j][k]=m[i+1][j][k];
for(int j=w[i];j<=c;j++)
for(int k=b[i];k<=d;k++)
m[i][j][k]=max(m[i+1][j][k],m[i+1][j-w[i]][k-b[i]]+v[i]);
}
m[1][c][d]=m[2][c][d];
if(c>=w[1]&&d>=b[1])m[1][c][d]=max(m[2][c][d],m[2][c-w[1]][d-b[1]]+v[1]);
}
void Traceback(int m[][11][11],int *w,int c,int *b,int d,int n,int *x)
{
for(int i=1;i if(m[i][c][d]==m[i+1][c][d])x[i]=0;
else
{
x[i]=1;
c-=w[i];
d-=b[i];
}
x[n]=(m[n][c][d])?1:0;
}
int main()
{
int v[]={0,2,6,2,6,8},w[]={0,2,5,3,4,6},b[]={0,1,4,3,2,5},m[6][11][11],x[6]={0};//w[],b[]为重量或其他限定条件的份额,v[]为价值
int n=5,c=10,d=10;
int i,j,k;
for(i=0;i<6;i++)
for(j=0;j<11;j++)
for(k=0;k<11;k++)
m[i][j][k]=0;
Knapsack(v,w,c,b,d,n,m);
cout< Traceback(m,w,c,b,d,n,x);
for(i=1;i<6;i++)
cout< system("pause");
return 0;
}

你可能感兴趣的:(多个限定条件下的背包问题)