题意:wzc有n份面粉,有m种糕点可以制作。每种糕点的制作除了面粉之外还需要对应的馅料(每种糕点与其馅料是一一对应的)。对于第i种糕点,目前剩余的对应馅料还有ai份,制作一份糕点需要bi份馅料和ci份面粉,可以销售处di元钱。当然他也可以选择不加馅料直接卖,利用c0的面粉制作出一份糕点,可以售出d0元钱。
分析:多重背包,我们可以把c0的面粉当作另一种物品,当循环前面的糕点时,就可以正确地计算出答案。我们定义\(f[i][j]:\)前i种糕点,j个体积的最大收益,我们的\(DP转移方程式:f[i][j] = max(f[i][j], f[i - 1][j - k * b[i]] + k * d[i]),并且k * b[i] <= a[i]且k * c[i] <= j\)。我们把剩下的不加馅料的面粉也计算进来,就可以求出整个最大收益了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int N = 1005;
struct Node
{
int a, b, c, d;
}p[N];
int f[15][1500];
int main()
{
int n, m, c0, d0;
scanf("%d%d%d%d", &n, &m, &c0, &d0);
for (int i = 1; i <= m; ++i) scanf("%d%d%d%d", &p[i].a, &p[i].b, &p[i].c, &p[i].d);
for(int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
{
for (int k = 0; k * p[i].b <= p[i].a && k * p[i].c <= j; ++k)
{
f[i][j] = max(f[i][j], f[i - 1][j - k * p[i].c] + k * p[i].d);
}
}
for (int j = 1; j <= n; ++j)
{
for (int k = 0; k * c0 <= j; ++k)
{
f[m + 1][j] = max(f[m + 1][j], f[m][j - k * c0] + k * d0);
}
}
printf("%d\n", f[m + 1][n]);
return 0;
}