01背包

01背包

代码存档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<bits/stdc++.h>
#define N 1000
#define MAX 10000
using namespace std;
int c[N],w[N];


//递归写法
int make(int i,int j)//递归实现01背包,i为第i件商品,j为剩余容量,初始时i=max,j=max
{
if(i==0) return 0;
if(j>=w[i]) return max(make(i-1,j),make(i-1,j-w[i])+c[i]);
else return make(i-1,j);
}

int BagVer1(int n,int v)//动态规划实现01背包,i为第i件商品,j为剩余容量,n为商品数量,v为体积,f[i][j]为此状态下的最大价值
{
int f[n*2][MAX];//不能开MAX*MAX因为空间不够
for (int i = 1; i <= n; i++)
f[i][0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= v; j++)
if (j >= w[i])//背包容量够大
f[i][j] = max(f[i - 1][j - w[i]] + c[i], f[i - 1][j]);
else//背包容量不足
f[i][j] = f[i - 1][j];
return f[n][v];
}

int BagVer2(int n,int v) //动态规划01背包的空间压缩写法
{
int f[MAX];
f[0]=0;
for(int i=1;i<=n;i++)
for(int j=v;j>=1;j--)//从后往前遍历防止前面的已经被更新过的点干扰结果
if(j>=w[i]) f[j]=max(f[j-w[i]]+c[i],f[j]);
return f[v];
}

int BagVer3(int n,int v) //代码压行
{
int f[MAX];
f[0]=0;
for(int i=1;i<=n;i++)
for(int j=v;j>=w[i];j--)
f[j]=max(f[j-w[i]]+c[i],f[j]);
return f[v];
}

int main()
{
int n,v;//n为数目,v为背包上限
cin >> n >> v;
for (int i = 1; i <= n; i++)
cin >> c[i];//价值
for (int i = 1; i <= n; i++)
cin >> w[i];//体积
cout<<make(n,v)<<endl;
//while(1);
cout<<BagVer1(n,v)<<endl;
cout<<BagVer2(n,v)<<endl;
cout<<BagVer3(n,v)<<endl;
return 0;
}