题意:
有1, 5, 10三种硬币,分别有n1, n5, n10个,用来买c罐可乐。
每次只能买一罐,并且机器会自动按照用最少的硬币来组合最多的钱来找零。
问最少投入多少硬币,才能买到c罐可乐。(口袋里面的钱一定够买c可乐)
思路:
开辟三维数组记忆化搜索,很简单。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
using namespace std;
int dp[800][200][100];
int solve(int n, int a, int b, int c)
{
if (n == 0)
return 0;
else 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 cases;
scanf("%d", &cases);
while (cases--)
{
int n, a, b, c;
scanf("%d %d %d %d", &n, &a, &b, &c);
memset(dp, -1, sizeof(dp));
dp[0][0][0] = 0;
solve(n, a, b, c);
printf("%d\n", dp[a][b][c]);
}
return 0;
}