Problem D
Buying Coke
Input:StandardInput
Output: Standard Output
Time Limit: 2 Seconds
I often buy Coca-Cola from the vending machine atwork. Usually I buy several cokes at once, since my working mates also likes coke.A coke in the vending machine costs8 Swedish crowns, and the machineaccept crowns with the values1, 5 and 10. As soon as Ipress the coke button (after having inserted sufficient amount of money), Ireceive a coke followed by the exchange (if any). The exchange is always givenin as few coins as possible (this is uniquely determined by the coin set used).This procedure is repeated until I've bought all the cokes I want. Note that Ican pick up the coin exchange and use those coins when buying further cokes.
Now, what is the least number of coins I mustinsert, given the number of cokes I want to buy and the number of coins I haveof each value? Please help me solve this problem while I create some harderproblems for you. You may assume that the machine won't run out of coins andthat I always have enough coins to buy all the cokes I want.
Input
The first line in the input contains the numberof test cases (at most 50). Each case is then given on a line by itself.A test case consists of four integers:C (the number of cokes I want tobuy),n1,n5, n10(the number of coins of value1,5 and 10, respectively).The input limits are1 <=C <= 150, 0 <= n1<= 500,0 <=n5 <= 100 and 0 <= n10<= 50.
Output
For each test case, output a line containing a singleinteger: the minimum number of coins needed to insert into the vending machine.
Sample Input Output for Sample Input
3 2 2 1 1 2 1 4 1 20 200 3 0 |
5 3 148
|
题目意思是说可乐8块钱1瓶,你有1块,5块,10块的,如果你丢进去钱超过8块,它会自动找你尽可能少的钱的张数,问你最少用几张钱能买到需要的可乐。
以前做记忆化搜索的时候,就觉得和DP基本差不多,只是求解的顺序不同,搜索函数几个参数保存状态的数组就开几维。。平时用递推比较多,现在才发现记忆化搜索真神奇。。
这道题一开始想的是开个四维数组,递推求出每个状态。结果根本开不下这么大的数组
(而且其实就算开下了也没有必要计算其中的很多状态)。看了别人的,发现是记忆化搜索,并且只用三维数组(dp[x][y][z],代表三种钱的张数并且还需要买c瓶可乐)保存计算过的状态。。其实确实可以,因为是通过递归一步一步求的,原来的总钱数减去每个状态的总钱数一定是8的倍数,这样dp[x][y][z]确定了还需要买的可乐也就确定了(c=C-(最开始总钱数-现在总钱数)/8)。也就是说根本不需要四维的数组。但是从底向上递推的话没有四维数组不好递推,用记忆化搜索就简单了,函数里有四个参数,保存状态的数组是三维。如果计算过或者c=0就返回。
有时候不好递推的时候记忆化搜索真的好用(时间复杂度和递推是一样的,常数级的时间用的多一些,但是省去了很多不必要又不好算的情况)~
这道题还有个特别要注意的地方,你给它3个1块和1个10块,它会找你一个5块。
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
int dp[800][250][100];
int DP(int c,int n1,int n2,int n3){
int &ans=dp[n1][n2][n3];
if(ans) return ans;
if(!c) return 0;
ans=INF;
if(n1>=8) ans=min(ans,DP(c-1,n1-8,n2,n3)+8);
if(n1>=3&&n2>=1) ans=min(ans,DP(c-1,n1-3,n2-1,n3)+4);
if(n2>=2) ans=min(ans,DP(c-1,n1+2,n2-2,n3)+2);
if(n3>=1) ans=min(ans,DP(c-1,n1+2,n2,n3-1)+1);
if(n1>=3&&n3>=1) ans=min(ans,DP(c-1,n1-3,n2+1,n3-1)+4);
return ans;
}
int main(){
freopen("in.txt","r",stdin);
int T,C,N1,N2,N3;
scanf("%d",&T);
while(T--){
memset(dp,0,sizeof(dp));
scanf("%d%d%d%d",&C,&N1,&N2,&N3);
printf("%d\n",DP(C,N1,N2,N3));
}
return 0;
}
解决购买可乐最小硬币数量问题
本文探讨了一个在自动售货机购买多瓶可乐时,如何使用最少数量的硬币完成交易的问题。通过分析硬币组合与所需购买的数量,采用记忆化搜索算法优化解决方案,有效减少了交易过程中所需的硬币总数。
1834

被折叠的 条评论
为什么被折叠?



