HDU 4501
小明系列故事-买年货
背包问题。不过有多个属性。
注意要点:
每种物品只有一件,需要从大到小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); } }