zoukankan      html  css  js  c++  java
  • 动态规划--换零钱

    想兑换100元钱,有1,2,5,10四种钱,问总共有多少兑换方法?

    递归解法

     1 #include<iostream>
     2 using namespace std; 
     3 
     4 const int N = 100;  
     5 int dimes[] = {1, 2, 5, 10};  
     6 int arr[N+1] = {1};  
     7 
     8 int coinExchangeRecursion(int n, int m) //递归方式实现,更好理解
     9 {  
    10   if (n == 0)   //跳出递归的条件
    11     return 1;  
    12   if (n < 0 || m == 0)  
    13     return 0; 
    14 
    15   return (coinExchangeRecursion(n, m-1) + coinExchangeRecursion(n-dimes[m-1], m));  
    16   //分为两种情况:换取当前面值的情况 + 没有换取当前面值的情况
    17 }
    18 
    19 int main()
    20 {
    21   int num=coinExchangeRecursion(N, 4); 
    22   cout<<num<<endl; 
    23 
    24   return 0; 
    25 
    26 }

    非递归解法

     1 #include<iostream>
     2 using namespace std; 
     3 
     4 const int N = 100;  
     5 int dimes[] = {1, 2, 5, 10};  
     6 int arr[N+1] = {1};  
     7 
     8 int coinExchange(int n)   //非递归实现
     9 {  
    10   int i, j;  
    11   //i从0 ~ 3     因为每个arr[j]都要有一次是假设兑换了dimes[i],所以我们要遍历一次
    12   for (i = 0; i < sizeof(dimes)/sizeof(int); i++)
    13   {  
    14     for (j = dimes[i]; j <= n; j++)   
    15       //求,arr[j]的时候,可以看出arr[j] = arr[j] + arr[j-dimes[i]],
    16       //对应着上面的递归方式:arr[j]就是coinExchangeRecursion(n, m-1),
    17       //arr[j-dimes[i]]就是coinExchangeRecursion(n-dimes[m-1], m)
    18       arr[j] += arr[j-dimes[i]];  
    19 
    20   }  
    21   return arr[n];  
    22 }  
    23 
    24 
    25 int main()
    26 {
    27   int num2=coinExchange(N); 
    28   cout<<num2<<endl; 
    29 
    30   return 0;
    31 }

    方法总结

    动态规划的经典之处把大问题分解成几个小问题解决 
    递归算法:100元的换法:零钱中有此面值与零钱中没此面值的两种情况,注意递归结束的条件 
    非递归算法:换100的零钱,那么先从换1、2、……的零钱算起,这个算法,最好转换成台阶走法的问题来理解 
    仔细推理可以看出arr[j] = arr[j-dimes[0]] + arr[j-dimes[1]] + arr[j-dimes[2]] + arr[j-dimes[3]] (j-dimes[i]>=0)

     1 #include<iostream>
     2 #include<vector>     //std::vector
     3 #include <algorithm> //std::count
     4 using namespace std; 
     5 
     6 const int N = 100;  
     7 int dimes[] = {1, 2, 5, 10};  
     8 int arr[N+1] = {1}; 
     9 vector<int> vv; 
    10 
    11 int coinExchangeRecursion(int n, int m) //递归方式实现,更好理解
    12 {  
    13     if (n == 0) {
    14         int i;
    15         for (i = 0; i < sizeof(dimes)/sizeof(int); i++) {
    16             int cnt = count(vv.begin(), vv.end(), dimes[i]);
    17             cout << dimes[i] << ": " << cnt << "	";
    18         }
    19         cout  << endl;
    20         return 1;  
    21     }   //跳出递归的条件
    22     if (n < 0 || m == 0)  
    23     return 0;
    24     vv.push_back(dimes[m-1]);
    25     int yes = coinExchangeRecursion(n-dimes[m-1], m);
    26     vv.pop_back();
    27     int no = coinExchangeRecursion(n, m-1);
    28     return (no+yes);  
    29     //分为两种情况,如果没有换当前硬币,那么是多少?加上,如果换了当前硬币,总值减少,此时又是多少种兑换方法?
    30 }
    31 
    32 int coinExchange(int n)   //非递归实现
    33 {  
    34     int i, j;  
    35     for (i = 0; i < sizeof(dimes)/sizeof(int); i++)   //i从0 ~ 3     因为每个arr[j]都要有一次是假设兑换了dimes[i],所以我们要遍历一次
    36     {  
    37         for (j = dimes[i]; j <= n; j++)   
    38             //求,arr[j]的时候,可以看出arr[j] = arr[j] + arr[j-dimes[i]],
    39             //对应着上面的递归方式:arr[j]就是 coinExchangeRecursion(n, m-1),
    40             //arr[j-dimes[i]]就是coinExchangeRecursion(n-dimes[m-1], m)
    41             arr[j] += arr[j-dimes[i]];  
    42     }  
    43     return arr[n];  
    44 }  
    45 
    46 int main(int argc, char *argv[])
    47 {
    48     int num=coinExchangeRecursion(N, 4); 
    49     cout<<num<<endl; 
    50 
    51     int num2=coinExchange(N); 
    52     cout<<num2<<endl; 
    53 
    54     return 0; 
    55 }

    参考链接:

    http://www.cnblogs.com/sdjl/articles/1274312.html 

    https://www.tuicool.com/articles/VBreAnY

    转载请说明出处!
  • 相关阅读:
    Sql server
    分布式爬虫
    爬取某电影网站最新电影
    随笔写一个简单的爬虫
    python的os模块
    基于python的文件处理
    mysql习惯及主从复制参数设置
    git常用命令
    git实习笔记
    微信公众平台开发接口PHP SDK完整版
  • 原文地址:https://www.cnblogs.com/zengshangzhi/p/8881882.html
Copyright © 2011-2022 走看看