这道题我们可以想成对于每个主件如何进行购买的问题,我们可以不买,只买主件,买主件和附件1,买主件和附件2,都买,然后选择其最佳方案。这样本题就是一个01背包的问题了。即可得出状态转移方程
f[j] = max(f[j], f[j - a[i]] + b[i]);
if (j - a[i] - d[i][1] >= 0)
f[j] = max(f[j], f[j - a[i] - d[i][1]] + b[i] + e[i][1]);
if (j - a[i] - d[i][2] >= 0)
f[j] = max(f[j], f[j - a[i] - d[i][2]] + b[i] + e[i][2]);
if (j - a[i] - d[i][1] - d[i][2] >= 0)
f[j] = max(f[j], f[j - a[i] - d[i][1] - d[i][2]] + b[i] + e[i][1] + e[i][2]);
下面附上代码
#include <iostream>
using namespace std;
const int N = 61;
int n, m;
int a[N], b[N], c[N], d[N][3], e[N][3], f[32005];//d,e数组用来存储附件
int x, y, z;
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
cin >> x >> y >> z;
if (z == 0)
{
a[i] = x;
b[i] = x * y;
}
if (z != 0)//标记附件
{
d[z][0]++;
d[z][d[z][0]] = x;
e[z][d[z][0]] = x * y;
}
}
for (int i = 1; i <= m; i++)
for (int j = n; j >= a[i] && a[i] != 0; j--)
{
f[j] = max(f[j], f[j - a[i]] + b[i]);
if (j - a[i] - d[i][1] >= 0)
f[j] = max(f[j], f[j - a[i] - d[i][1]] + b[i] + e[i][1]);
if (j - a[i] - d[i][2] >= 0)
f[j] = max(f[j], f[j - a[i] - d[i][2]] + b[i] + e[i][2]);
if (j - a[i] - d[i][1] - d[i][2] >= 0)
f[j] = max(f[j], f[j - a[i] - d[i][1] - d[i][2]] + b[i] + e[i][1] + e[i][2]);
}
cout << f[n];
return 0;
}