本人刚入门dp,水平较菜,因此记录自己对于此题的代码思路,为确保自己能看懂,进行了连我都能看懂的备注,希望能帮到刚入门的同学,也为自己复习留一份记录。
二维做法:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1005;
int f[N][N];
int v[N]; // 体积
int w[N]; // 价值
int main()
{
int n, maxv;
cin >> n >> maxv;
for (int i = 1; i <= n; i ++ )
{
cin >> v[i] >> w[i];
}
for(int i = 1; i <= n; i ++ )//尝试装入n个物品
{
for (int j = 1; j <= maxv; j ++ )//最大体积为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]);//前者为不选,后者为选择
}
}
}
cout << f[n][maxv] << endl;
return 0;
}
一维做法
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1005;
int f[N];
int v[N]; // 体积
int w[N]; // 价值
int main()
{
int n, maxv;
cin >> n >> maxv;
for (int i = 1; i <= n; i ++ )
{
cin >> v[i] >> w[i];
}
for(int i = 1; i <= n; i ++ )//尝试装入n个物品
{
for (int j = maxv; j >= 0; j -- )//最大体积为j时能装入物品的最大价值
//此处j亦可等于1,由于判断时背包容量大小为0不对原f产生影响(空间为0因此一定装不进去)
//关于此处j从大到小循环:
//从上面二维代码中可看出一维实际为默认二维第一位为i
//而转移方程中会出现i- 1的情况,若从小到大进行背包体积的枚举更新
//则34行中f[j - v[i]]实际使用的为第i轮的结果,而非i-1轮,出现错误
{
if(j < v[i])//当剩余体积不够放入时,此时最大价值等于不放入该物体的最大价值
{
f[j] = f[j];
}
else//否则则判断是否选择该物品
{
f[j] = max(f[j], f[j - v[i]] + w[i]);//前者为不选,后者为选择
}
}
}
cout << f[maxv] << endl;
return 0;
}