01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为C1,C2,…,Cn,与之相对应的价值为W1,W2,…,Wn.求解将那些物品装入背包可使总价值最大。
1) 子问题定义:F[i][j]表示前i件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值。
2) 根据第i件物品放或不放进行决策
其中F[i-1][j]表示前i-1件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值;
而F[i-1][j-C[i]]+W[i]表示前i-1件物品中选取若干件物品放入剩余空间为j-C[i]的背包中所能取得的最大价值加上第i件物品的价值。
根据第i件物品放或是不放确定遍历到第i件物品时的状态F[i][j]。
设物品件数为N,背包容量为V,第i件物品体积为C[i],第i件物品价值为W[i]。转载于http://blog.youkuaiyun.com/wumuzi520/article/details/7014830
01装满背包
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int facs(int Weight[], int nLen, int capacity)
{
int * a= new int [capacity+1];
memset(a,0,(capacity+1)*sizeof(int));
a[0] = 1;
for(int i = 0; i < nLen; i++)
{
for(int j = nCapacity; j >=Weight[i]; j--)//为什么这里要逆序,其实我们这里是改进的代码因为我们要保证a[j]是i-1时刻的值
{
if(j >= Weight[i])
a[j] += a[j-Weight[i]];
}
}
int k = a[capacity];
delete [] a;
return k;
}
01背包问题#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int facs(int Weight[], int Len, int capacity,int value[])
{
int * a= new int [capacity+1];
memset(a,0,(capacity+1)*sizeof(int));
for(int i = 1; i < Len; i++)
{
for(int j = Capacity; j >=Weight[i]; j--)//为什么这里要逆序,其实我们这里是改进的代码因为我们要保证a[j]是i-1时刻的值
{
a[j]=max(a[j],a[j-Weight[i]]+value[i]);
}
}
int k = a[capacity];
delete [] a;
return k;
}
打印构成最大背包的物品
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int facs(int Weight[], int nLen, int capacity,int value[])
{
int * a= new int [capacity+1];
int Path[100][100];
memset(a,0,(capacity+1)*sizeof(int));
for(int i = 1; i < Len; i++)
{
Path[i][j] = 0;
for(int j = nCapacity; j >=Weight[i]; j--)//为什么这里要逆序,其实我们这里是改进的代码因为我们要保证a[j]是i-1时刻的值
{
a[j]=max(a[j],a[j-Weight[i]]+value[i]);
Path[i][j] = 1;
}
}
int i = Len, j = capacity;
while(i > 0 && j > 0)
{
if(Path[i][j] == 1)
{
cout << Weight[i-1] << " ";
j -= Weight[i-1];
}
i--;
}
}
完全背包问题下方是转满这个背包有几种方案
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<map>
#include<string>
#define INF 0x7fffffff
using namespace std;
int Package02_FullOfPackage_Compress(int Weight[], int nLen, int nCapacity)
{
int * MethodTable = new int [nCapacity+1];
memset(MethodTable,0,(nCapacity+1)*sizeof(int));
MethodTable[0] = 1;
for(int i = 0; i < nLen; i++)
{
for(int j = Weight[i]; j <= nCapacity; j++)
{
if(j >= Weight[i])
MethodTable[j] += MethodTable[j-Weight[i]];
}
}
int nRet = MethodTable[nCapacity];
delete [] MethodTable;
return nRet;
}
int main()
{
int Weight[] = {5,10};
int nCapacity = 20;
cout << "AllCount:" << Package02_FullOfPackage_Compress(Weight,2,nCapacity) << endl;
return 0;
}
完全背包是在N种物品中选取若干件(同一种物品可多次选取)放在空间为V的背包里,每种物品的体积为C1,C2,…,Cn,与之相对应的价值为W1,W2,…,Wn.求解怎么装物品可使背包里物品总价值最大。
int Package02_Compress(int Weight[], int Value[], int nLen, int nCapacity)
{
int * Table = new int [nCapacity+1];
memset(Table,0,(nCapacity+1)*sizeof(int));
for(int i = 0; i < nLen; i++)
{
for(int j = Weight[i]; j <=nCapacity; j++)
{
if(Table[j] < Table[j-Weight[i]]+Value[i])
{
Table[j] = Table[j-Weight[i]]+Value[i];
}
}
}
int nRet = Table[nCapacity];
delete [] Table;
return nRet;
}