思路:
-
初始化:
- 使用一个数组
f
来存储每个金额所需的最少硬币数量。数组大小为11451419
,足够存储最大金额10^6
的结果。 - 使用
memset
将数组f
初始化为-1
,表示所有金额的硬币数量尚未计算。
- 使用一个数组
-
深度优先搜索(DFS):
- 定义一个递归函数
dfs(int x)
,其中x
是当前需要凑出的金额。 - 如果金额
x
为 0,则不需要任何硬币,返回 0。 - 如果
f[x]
已经被计算过(即f[x] != -1
),则直接返回f[x]
。 - 初始化
minmoney
为一个很大的数(1e9),用于存储当前金额x
所需的最少硬币数量。 - 遍历所有可能的硬币面值
{1, 5, 11}
,如果当前金额x
大于等于某个面值money
,则递归计算x - money
所需的最少硬币数量,并加上一枚硬币(+1
)。 - 更新
minmoney
为所有可能面值中所需硬币数量的最小值。 - 将计算结果存储在
f[x]
中,并返回f[x]
。
- 定义一个递归函数
-
主函数:
- 从标准输入读取金额
xx
。 - 调用
dfs(xx)
计算所需的最少硬币数量,并输出结果。
- 从标准输入读取金额
代码1:
#include<bits/stdc++.h>
using namespace std;
int f[11451419];
int main()
{
int n;
cin>>n;
for(int i = 1;i <= n;i++)
{
int cost = INT_MAX;
if(i - 1 >= 0) cost = min(cost, f[i - 1] + 1);
if(i - 5 >= 0) cost = min(cost, f[i - 5] + 1);
if(i - 11 >= 0) cost = min(cost, f[i - 11] + 1);
f[i] = cost;
}
cout<<f[n];
return 0;
}
代码2:
#include<bits/stdc++.h>
using namespace std;
int xx,f[11451419];
int dfs(int x){
if(x == 0) return 0;
if(f[x]!= -1) return f[x];
int minmoney = 1e9;
for(int money : {1,5,11}){
if(x >= money){
int moneys = dfs(x - money) + 1;
minmoney = min(minmoney, moneys);
}
}
f[x] = minmoney;
return f[x];
}
int main(){
memset(f, -1, sizeof(f));
cin>>xx;
cout<<dfs(xx)<<endl;
return 0;
}