UVA - 10626 Buying Coke

题目大意:给出要买可乐的数量, 以及1元,5元和10元硬币的数量, 每瓶可乐8元,每次照钱会按照最少硬币的方式找回, 问如何投币可使得投入的硬币数最少, 输出最少硬币值。


解题思路:记忆化搜索, 因为可乐每购买一次便要找会硬币,所以对与每个状态考虑的情况比并不是很多。


注意:1、每够买一次可乐便会找回一次硬币,所以不用考虑的太复杂。

2、题目中虽然说1元不超过500个,但是开的记录数组一定要比500大,大约700左右,因为要考虑找回金额的情况。


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
using namespace std;

int DP[800][200][100];

int solve(int n, int a, int b, int c) {
	if (n == 0)
		return 0;
	if (DP[a][b][c] != -1)
		return DP[a][b][c];

	DP[a][b][c] = INT_MAX;
	if (c >= 1)
		DP[a][b][c] = min(DP[a][b][c], solve(n-1, a+2, b, c-1) + 1);
	if (a >= 3 && b >= 1)
		DP[a][b][c] = min(DP[a][b][c], solve(n-1, a-3, b-1, c) + 4);
	if (a >= 3 && c >= 1)
		DP[a][b][c] = min(DP[a][b][c], solve(n-1, a-3, b+1, c-1) + 4);
	if (b >= 2)
		DP[a][b][c] = min(DP[a][b][c], solve(n-1, a+2, b-2, c) + 2);
	if (a >= 8)
		DP[a][b][c] = min(DP[a][b][c], solve(n-1, a-8, b, c) + 8);

	return DP[a][b][c];
}

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		int n, a, b, c;
		scanf("%d%d%d%d", &n, &a, &b, &c);
		memset(DP, -1, sizeof(DP));
		DP[0][0][0] = 0;
		printf("%d\n", solve(n, a, b, c));
	
	}
	return 0;
}


你可能感兴趣的:(UVA - 10626 Buying Coke)