01背包问题:
每个物品只能选择一次,给定背包的最大承重量total和每个物品i的重量weight[i]和价值value[i],求背包可以装下的最大价值
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int num, total;
cin >> num >> total;
vector<int> weight(num+1);
vector<int> value(num+1);
for (int i = 1; i <= num; i++)
{
cin >> weight[i] >> value[i];
}
vector<vector<int>> f(num+1, vector<int>(total+1, 0));
for (int i = 1; i <= num; i++)
{
for (int j = total; j >= 1; j--)
{
if (j >= weight[i])
{
f[i][j] = max(f[i - 1][j], f[i - 1][j - weight[i]] + value[i]);
}
}
}
cout << f[num][total] << endl;
return 0;
}
优化之后:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int num, total;
cin >> num >> total;
vector<int> weight(num+1);
vector<int> value(num+1);
for (int i = 1; i <= num; i++)
{
cin >> weight[i] >> value[i];
}
vector<int> f(total+1, 0);
for (int i = 1; i <= num; i++)
{
for (int j = total; j >= 1; j--)
{
if (j >= weight[i])
{
f[j] = max(f[j], f[j - weight[i]] + value[i]);
}
}
}
cout << f[total] << endl;
return 0;
}
完全背包问题:
基本题意和01背包问题一样,只不过在选择物品过程中每个物品可以选择多次
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int num, total;
cin >> num >> total;
vector<int> weight(num+1);
vector<int> value(num+1);
vector<vector<int>> f(num + 1, vector<int>(total + 1, 0));
for (int i = 1; i <= num; i++)
{
cin >> weight[i] >> value[i];
}
for (int i = 1; i <= num; i++)
{
for (int j = 1; j <= total; j++)
{
if (j >= weight[i])
{
f[i][j] = max(f[i - 1][j], f[i][j - weight[i]] + value[i]);
}
}
}
cout << f[num][total] << endl;
return 0;
}
优化之后:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int num, total;
cin >> num >> total;
vector<int> weight(num+1);
vector<int> value(num+1);
vector<int> f(total+1);
for (int i = 1; i <= num; i++)
{
cin >> weight[i] >> value [i];
}
for (int i = 1; i <= num; i++)
{
for (int j=1;j<=total;j++)
{
if (j>=weight[i])
{
f[j] = max(f[j], f[j - weight[i]] + value[i]);
}
}
}
cout << f[total] << endl;
return 0;
}
区别1:
01背包问题的状态转移矩阵为:
f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i])
f[j]=max(f[j],f[j-weight[i]]+value[i])
完全背包的状态转移矩阵为:
f[i][j]=max(f[i-1],f[i][j-weight[i]]+value[i])
f[j]=max(f[j],f[j-weight[i]]+value[i])
区别2:
01背包矩阵遍历剩余承重量时倒序,完全背包遍历时正序。