[ABC 099] C-Strange Bank
C - Strange Bank
Time limit : 2sec / Memory limit : 256MB
Score : 300 points
Problem Statement
To make it difficult to withdraw money, a certain bank allows its customers to withdraw only one of the following amounts in one operation:
-
1 yen (the currency of Japan)
-
6 yen, 62(=36) yen, 63(=216) yen, ...
-
9 yen, 92(=81) yen, 93(=729) yen, ...
At least how many operations are required to withdraw exactly N yen in total?
It is not allowed to re-deposit the money you withdrew.
Constraints
- 1≤N≤100000
- N is an integer.
[题目解释]
现在我们要取出n元钱,每一次取只能取出1,6m,9m(m>0且m为整数)元,问我们最少要取几次?
[题目解析]
这道题类似于完全背包问题,但不同的是问在刚好取出n元的情况下最小代价为多少,我们可以预处理出一次取钱的所有情况其代价为1,我们记一个数组f[],f[i]表示取出i元最小代价为f[i],由于我们可以1元1元地取,取出i元的最大代价为i(即一定可以恰好取出i元),我们尝试是否能放进其他物品,使其代价更小,若更小就更新答案.方程为f[i]=min(f[i-thing[j]]+1);其中thing[]为预处理出每一次可以取出的钱数;
[代码]
/* Name: Strange Bank Author: FZSZ-LinHua Date: 2018 06 10 Exec time: 13ms Memory usage: 640KB Score: 300 Algorithm: Dynamic programming */ # include "iostream" # include "cstdio" # include "cstring" using namespace std; const int maxm=100000+10; int f[maxm],n; int thing[maxm],tot; //thing[i]为预处理出每一次可以取出钱的所有情况,一个有tot种 int main(){ thing[++tot]=1; //一次可以取出1元 register int i,j; memset(f,0x3f,sizeof(f)); //先给f数组赋一个较大值 scanf("%d",&n); i=6; while(i<=n){ //枚举6的次幂 thing[++tot]=i; i*=6; } i=9; while(i<=n){ //枚举9的次幂 thing[++tot]=i; i*=9; } f[0]=0; for(i=1;i<=tot;i++){ //完全背包 for(j=thing[i];j<=n;j++){ f[j]=min(f[j],f[j-thing[i]]+1); } } printf("%d",f[n]); return 0; }

浙公网安备 33010602011771号