1. 程式人生 > >#154-[二維揹包DP]潛水員

#154-[二維揹包DP]潛水員

Description

    潛水員為了潛水要使用特殊的裝備。他有一個帶2種氣體的氣缸:一個為氧氣,一個為氮氣。讓潛水員下潛的深度需要各種的數量的氧和氮。潛水員有一定數量的氣缸。每個氣缸都有重量和氣體容量。潛水員為了完成他的工作需要特定數量的氧和氮。他完成工作所需氣缸的總重的最低限度的是多少?
 例如:潛水員有5個氣缸。每行三個數字為:氧,氮的(升)量和氣缸的重量:
    3 36 120
    10 25 129
    5 50 250
    1 45 130
    4 20 119

如果潛水員需要5升的氧和60升的氮則總重最小為249(1,2或者4,5號氣缸)。
你的任務就是計算潛水員為了完成他的工作需要的氣缸的重量的最低值。

Input

第一行有2整數m,n(1<=m<=21,1<=n<=79)。它們表示氧,氮各自需要的量。
第二行為整數k(1<=k<=1000)表示氣缸的個數。
此後的k行,每行包括ai,bi,ci(1<=ai<=21,1<=bi<=79,1<=ci<=800)3整數。這些各自是:第i個氣缸裡的氧和氮的容量及汽缸重量。

Output

僅一行包含一個整數,為潛水員完成工作所需的氣缸的重量總和的最低值。

Sample Input

5 60
5
3 36 120
10 25 129
5 50 250
1 45 130
4 20 119

Sample Output

249
#include <iostream>
#include <cstring>

#define SIZE 1010

using namespace std;

int dp[SIZE][SIZE];

int main(void)
{
	int n, i, j, k, t, t2, x, y, a, b, c;
	
	scanf("%d%d%d", &t, &t2, &n);
	
	memset(dp, 63, sizeof (dp));
	dp[0][0] = 0;
// dp[i][j] 表示還需i份氮氣和j份氧氣的最小重量
	for (i = 1; i <= n; ++i)
	{
		scanf("%d%d%d", &a, &b, &c);
		for (j = t; ~j; --j)
		{
			x = min(j + a, t);
			for (k = t2; ~k; --k)
			{
				y = min(k + b, t2); // 確保不會超出範圍
				dp[x][y] = min(dp[x][y], dp[j][k] + c);
			}
		}
	}
	
	printf("%d", dp[t][t2]);
	
	return 0;
}