//题目:有三种硬币,币值为1、5、11,现在要拿出15价值,求最少硬币数拿法
//这种题目不能用贪心,枚举又太复杂,所以动态规划是首选
# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
# define MAX 100000000
int min(int x,int y){
return x<y?x:y;//三目运算符
}
int main()
{
int dp[100];
// memset(dp,0,sizeof(dp));
dp[0]=0;//这种是特殊情况,不能整个数组清空,清空的话,下面的数组是写了min函数比大小,整个硬币数组都清零了还怎么比大小。直接给出一堆零
int x;
cin>>x;
int i;
int cost;
for(i=1; i<=x; i++){
cost=MAX;
if(i-1>=0) cost=min(cost,dp[i-1]+1);//加1时表示加进去的一枚硬币
if(i-5>=0) cost=min(cost,dp[i-5]+1);//这几个if根据题目条件去写
if(i-11>=0) cost=min(cost,dp[i-11]+1);//原理在视频链接的末尾。 需要层层递推,选出每一种价值的最优解,然后根据三种币值选一种,比如1开头,5开头,11开头,就是说至少有一个,然后剩下的价值根据之前推出来的最优解去做加法得出
dp[i]=cost;
cout<<dp[i]<<endl;
}
// for(i=1; i<=x; i++)
// cout<<dp[x]<<endl;
return 0;
}
学习链接:【动态规划 硬币问题】 https://www.bilibili.com/video/BV1G7411B7Et/?share_source=copy_web&vd_source=47859ce1ab05f03eb31349dd833264f2