动态规划是一种算法思想,可以简单解释为将复杂问题分解为许多个子问题,在无后效性的前提下一一解决,最后得到原复杂问题的最优解。
1.最少硬币问题
有n种硬币,面值为v1,v2,....vn,数量无限。输入非负整数s,选用硬币,使其和为s。输出最少硬币的组合的数量。
易得其状态转移方程为ans[i]=min(ans[i],ans[i-v[j]]+1) (j=1,2...n)其中ans[i]表示硬币之和,v[j]表示硬币种类,此题本质为背包问题。
2.打印最少硬币的组合
把dp的代码改为:
if(ans[i]>ans[i-v[i]]+1){//用的硬币变了 ans_path[i]=v[i]; //在每个金额上记录路径,即某个硬币的面值 ans[i]=ans[i-v[i]]+1; //递推式 }
3.所有硬币组合
有n种硬币,面值为v1,v2,....vn,数量无限。输入非负整数s,选用硬币,使其和为s。输出所有可能的硬币组合的数量。
其状态转移方程为dp[i]+=dp[i-v[j]] (j=1,2,3,...n)
例题
Coin Change
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 34000 Accepted Submission(s): 12212
Problem Description
Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money.
For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-cent coin, or two 5-cent coins and one 1-cent coin, or one 5-cent coin and six 1-cent coins, or eleven 1-cent coins. So there are four ways of making changes for 11 cents with the above coins. Note that we count that there is one way of making change for zero cent.
Write a program to find the total number of different ways of making changes for any amount of money in cents. Your program should be able to handle up to 100 coins.
For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-cent coin, or two 5-cent coins and one 1-cent coin, or one 5-cent coin and six 1-cent coins, or eleven 1-cent coins. So there are four ways of making changes for 11 cents with the above coins. Note that we count that there is one way of making change for zero cent.
Write a program to find the total number of different ways of making changes for any amount of money in cents. Your program should be able to handle up to 100 coins.
Input
The input file contains any number of lines, each one consisting of a number ( ≤250 ) for the amount of money in cents.
Output
For each input line, output a line containing the number of different ways of making changes with the above 5 types of coins.
Sample Input
11
26
Sample Output
4
13
此题与3的区别在于硬币的数量有限,这就需要建立第二个维度来存储硬币的数量这个状态了。
我们设dp[i][j]为使用了j个硬币,和为i的方案数量。
其状态转移方程为:dp[i][j]+=dp[i-v[k]][j-1]。即使用了j个硬币,和为i的方案数量为原数量加上使用了j-1个硬币何为i-v[k]的方案数,其中v[k]表示第k种硬币的金额。
代码如下所示
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int v[5]={1,5,10,25,50}; int dp[255][105]; int main(){ memset(dp,0,sizeof(dp)); dp[0][0]=1; int n; for(int k=0;k<=4;k++){ for(int j=1;j<=100;j++){ for(int i=v[k];i<=250;i++){ dp[i][j]+=dp[i-v[k]][j-1]; } } } int ans[255]={0}; for(int i=0;i<=250;i++){ for(int j=0;j<=100;j++){ ans[i]+=dp[i][j]; } } while(~scanf("%d",&n)){ printf("%d\n",ans[n]); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧