• dp算法之硬币找零问题


    题目:硬币找零

    题目介绍:现在有面值1、3、5元三种硬币无限个,问组成n元的硬币的最小数目?

    分析:现在假设n=10,画出状态分布图:

    硬币编号 硬币面值p
    1 1
    2 3
    3 5
    编号i/n总数j 0 1 2 3 4 5 6 7 8 9 10
    1 0 1 2 3 4 5 6 7 8 9 10
    2 0 1 2 1 2 3 2 3 4 3 4
    3 0 1 2 1 2 1 2 3 2 3 2

    设所需硬币最小数目为m,则可以看出m[ i ][  j ]=m[ i-1 ][  j-k*p[ i ]] + k.其中k*p[ i ]<=j.确切的说,k=j/p[ i ].

    dp算法的显著特征之一就是具有最优子结构,且这一状态的最优解与上一状态的最优解有关。写出状态方程之后我们就可以开始具体处理代码了。

     1 #include <iostream>
     2 using namespace std;
     3 int main()
     4 {
     5     int i, j, k;
     6     int m, n;//m就是总值
     7     cout << "总数:" << endl;
     8     cin >> m;
     9     //m = 10, ;
    10     n = 3;
    11     int **c = new int *[n + 1];
    12     for (i = 0; i <= n; i++)
    13     {
    14         c[i] = new int[m + 1];
    15     }
    16     int p[4] = { 0,1,3,5 };
    17     for (i = 0; i <= n; i++)
    18     {
    19         for (j = 0; j <= m; j++)
    20         {
    21             c[i][j] = 0;//初始化
    22         }
    23     }
    24     for (i = 1; i <= n; i++)
    25     {
    26         for (j = 1; j <= m; j++)
    27         {
    28             k = j / p[i];
    29             c[i][j] = c[i - 1][j - k * p[i]] + k;
    30         }
    31     }
    32     for (i = 1; i <= n; i++)
    33     {
    34         for (j = 0; j <= m; j++)
    35         {
    36             cout << c[i][j] << " ";
    37         }
    38         cout << endl;
    39     }
    40     return 0;
    41 }

    分析:这个硬币找零问题在dp算法中比较经典,复杂度低于经典的背包问题,因为背包问题还要考虑 k 的值,需要遍历 k 的值来找到一个最优解,此题不需要。

    结果:

    下一篇将要分析经典的背包问题了,包括01背包、完全背包、多重背包。

  • 相关阅读:
    Linux上的SQL Server的起步
    SQL Server 2016 SP1 标准版等同企业版?!
    为什么简单恢复模式模式真的是坏主意?
    在SQL Serve里停用行和页层级锁
    SQL Server里的闩锁耦合(Latch Coupling)
    我有几个NUMA节点
    SQL Server里在文件组间如何移动数据?
    对于SQL Server,我需要多少内存
    SQL Server里的文件和文件组
    重启SQL Server——总是好事?
  • 原文地址:https://www.cnblogs.com/ljy1227476113/p/9675145.html
Copyright © 2020-2023  润新知