(dp入门)换硬币

Posted xusi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(dp入门)换硬币相关的知识,希望对你有一定的参考价值。

有2元的 5元的 7元的 硬币若干,凑出27元,需要最小硬币数

这是一个动态规划问题,对动态规划求解的思路如下:

技术图片

 

 

1.确定状态:确定最后一步和倒数第二步之间的关系,就是把后面的问题转化为前面的子问题

x可以由x-2的情况再选面值2的硬币得到,也可以由x-5的情况选5面值的得到,还可以由x-7由面值7的得到

2.根据状态写出转移方程

dp[i]=min(dp[i-2]+1,dp[i-5]+1,dp[i-7]+1,dp[i]);

3.确定初始条件和边界情况

初始条件dp[0]=0

数组不能越界,考虑i-2和i-5和i-7的越界情况

#include<iostream>
#include<string.h>
#include<math.h>

using namespace std;
int n,m,k; 
int ans;
int mod=1e9+7;
int a[105];
bool vis[105]; 

int main(){
    cin>>n;
    memset(a,999999,sizeof(a));
    a[0]=0;
    for(int i=1;i<=n;i++){
        if(i>=2){
            a[i]=min(a[i],a[i-2]+1);
        }
        if(i>=5){
            a[i]=min(a[i],a[i-5]+1);
        }
        if(i>=7){
            a[i]=min(a[i],a[i-7]+1);
        }
    }
    cout<<a[n];
    return 0;
}

更一般的,告诉m种硬币的值每种值bi,求凑够n需要最小硬币数

#include<iostream>
#include<string.h>
#include<math.h>

using namespace std;
int n,m,k; 
int ans;
int mod=1e9+7;
int dp[105],b[105];
bool vis[105]; 

int main(){
    cin>>n>>m;                                // n:换的总钱价值  m:硬币总数 
    for(int i=0;i<m;i++){
        cin>>b[i];                            // 每种硬币的价值 
    }
    memset(dp,999999,sizeof(dp));             //初始化设置dp较大值 便于后面更新 
    dp[0]=0;                                  //初始条件 dp[0]=0 
    for(int i=1;i<=n;i++){                    //到 i 需要换的硬币最小个数 
        for(int j=0;j<m;j++){                 //依此考虑到 i 后每种硬币可能的换的最小个数  
            if(i>=b[j]){
                dp[i]=min(dp[i],dp[i-b[j]]+1);
            }
        }
    }
    cout<<dp[n];
    return 0;
}

 

以上是关于(dp入门)换硬币的主要内容,如果未能解决你的问题,请参考以下文章

经典动态规划:「换硬币」系列三道问题详解

Cg入门20:Fragment shader - 片段级模型动态变色(实现汽车动态换漆)

[Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

leetcode 面试题 硬币(dp)

DP——硬币问题

dp:硬币问题