[01背包1.0 关键代码] [c++]
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
int dfs(int x ,int spV, int sumW)
{
if(x>n) return 0;
else if(spV<v[x]) return dfs(x+1,spV,sumW);
else if(spv>=v[x])
{
return max(dfs(x+1,spV,sumW),dfs(x+1,spV-v[x],sumW+w[x]));
}
}
//记忆化搜索后
int dfs(int x ,int spV) //sumW不影响边界 抹去
{
if(mem[x][spV]) return mem[x][spV];
int sum=0;
if(x>n) sum= 0;
else if(spV<v[x]) sum= dfs(x+1,spV,sumW);
else if(spv>=v[x])
{
sum=max(dfs(x+1,spV,sumW),dfs(x+1,spV-v[x],sumW+w[x]));
}
mem[x][spV]=sum;
return sum;
}

//递推
for(int i=n;i>=1;i--) //从底部开始
{
for(int j=0;j<=m;j++)
{
if(j<v[i]) f[i][j]=f[i+1][j];
else f[i][j]=max(f[i+1][j],f[i+1][j-v[i]]+w[i]);
//就是直接dfs方程复制过来
}

}

cout<<f[1][m]; //终点是这个 第一个物品 体积是满的

当然可以优化成一维 我们只需要注意一个问题
为什么二维不用倒序 一维必须倒序呢?
十分简单的一个道理
由f[i][j]=max(f[i+1][j],f[i+1][j-v[i]]+w[i]) 此时的f[x][y]需是当前状态
若0-v枚举 如:i i i (i-1 i-1 i-1)
括号内是未更新的状态

若v-0枚举则规避了这个问题

[洛谷1048采药(01背包一维优化)] [c++]
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
#include<bits/stdc++.h>
using namespace std;

int n,m;
int t[10010],w[10010];
int f[100];

int main()
{
cin>>n>>m; //n是时间 m是数量
for(int i=1;i<=m;i++) cin>>t[i]>>w[i];
for(int i=m;i>=1;i--)
{
for(int j=n;j>=t[i];j--)
{
if(j<t[i]) f[j]=f[j];
else if(j>=t[i])
{
f[j]=max(f[j],f[j-t[i]]+w[i]);
}
}
}
cout<<f[n]<<endl;
}

[] [c++]
1
2
3
4