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);
	}
}


 

 

posted @ 2013-07-25 17:48  little_hsu  阅读(124)  评论(0编辑  收藏  举报