小明系列故事-买年货
背包问题。不过有多个属性。
注意要点:
每种物品只有一件,需要从大到小dp。
注意不要将一件物品放入多次。同代码。
#include <cstdio>
#include <cstring>
#include <iostream>
using std::memset;
using std::max;
int dp[101][101][6];
int goods[101][3];
int n,v1,v2,k;
int main()
{
while(scanf("%d%d%d%d", &n, &v1, &v2, &k)!=EOF)
{
for(int i = 0 ; i < n; i++)
{
scanf("%d%d%d", &goods[i][0], &goods[i][1], &goods[i][2]);
}
memset(dp, 0, sizeof(dp));
for(int i = 0 ; i < n; i++)
{
for(int j = v1 ; j >= 0; j--)
{
for(int l = v2; l >= 0; l--)
{
for(int m = k; m >= 0; m--)
{
int val1 = 0, val2 = 0, val3 = 0;
if(j >= goods[i][0])
{
val1 = dp[j-goods[i][0]][l][m] + goods[i][2];
}
if(l >= goods[i][1])
{
val2 = dp[j][l-goods[i][1]][m] + goods[i][2];
}
if(m >= 1)
{
val3 = dp[j][l][m-1] + goods[i][2];
}
dp[j][l][m] = max(val1, max(val2, max(dp[j][l][m], val3)));
//if(j >= goods[i][0]) // 这里不能这么写。因为此处的更新会导致一个物品放入了多次
//{
// dp[j][l][m] = max(dp[j-goods[i][0]][l][m] + goods[i][2], dp[j][l][m]);
//}
//if(l >= goods[i][1])
//{
// dp[j][l][m] = max(dp[j][l-goods[i][1]][m] + goods[i][2], dp[j][l][m]);
//}
//if(m >= 1)
//{
// dp[j][l][m] = max(dp[j][l][m-1] + goods[i][2], dp[j][l][m]);
//}
}
}
}
}
int ans = 0;
for(int i = 0 ; i <= v1; i++)
{
for(int j = 0 ; j <= v2; j++)
{
if(ans < dp[i][j][k])
{
ans = dp[i][j][k];
}
}
}
printf("%d\n", ans);
}
}