【算法】动态规划算法

简介: 【算法】动态规划算法

动态规划算法

走楼梯,可以一次上一阶,也可以,一次上两阶,根据楼梯的阶数来判断有几种上楼梯的方法。

分析

f(1) = 1; 1种

f(2) = 2; 2种

f(3) = f(1) + f(2);3种

f(4) = f(3) + f(2) ;5种

...

依次类推

代码如下:

#include<iostream>
using namespace std;

int WalkCount(int n)
{
    //可以一次走一阶台阶,也可以一次走两阶台阶
    if (n < 0)
    {
        return  0;
    }
    if (n == 1)
    {
        return 1;
    }
    if (n == 2)
    {
        return 2;
    }
    else {
        return WalkCount(n-1)+WalkCount(n-2);
    }
}
int main(void)
{
    cout << WalkCount(45) << endl;
    return 0;
}

我们发现,当楼梯结束过大的时,会因为内存消耗过大而发生栈溢出。

因为调用了大量重复的函数,将栈消耗光了。


解决办法:避免重复计算的部分,将重复计算的值保存下来。

long long  WalkCount(int n)
{

    long long  ret = 0;
    if (n <= 0)
    {
        return 0;
    }
    if (n == 1)
    {
        return 1;
    }
    if (n == 2)
    {
        return 2;
    }
    long long * value = new long long[n + 1];//索引从0开始
    value[0] = 0;
    value[1] = 1;
    value[2] = 2;

    for (int i = 3; i <= n; i++)
    {
        value[i] = value[i - 1] + value[i - 2];
    }

    ret = value[n];
    delete value;
    return ret;
}

动态规划算法也是一种分治的思想

分治算法是把原问题分解为若干子问题,自顶向下,求解子问题,合并子问题的解从而得到原问题的解。

动态规划也是自顶向下把原问题分解为若干子问题,不同的是然后,自底向上,先求解最小的子问题,把结果存储在表格中,在求解大的子问题时,直接从表格中查询小的子问题的解 ,避免重复计算,从而提高了算法效率。

(就是定义了一个数组存储之前得到的内容,累加到传进来的对应值。)

什么时候使用动态规划算法

如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能能够分解为若干子问题,并且小问题之间也存在 重叠的子问题,则考虑使用动态规划。

怎么使用动态规划

五部曲

  1. 判断题意是否找出一个问题的最优解。
  2. 从上往下分析问题,大问题可以分解为子问题,子问题中还有更小的问题。
  3. 从下网上分析问题,找出这些问题之间的关联(状态转移方程)。
  4. 讨论底层的边界问题。
  5. 解决问题(通常使用数组进行迭代求出最优解)

练习

给定一根线段,长为n,分成m段,最大的乘积是多少?

例如:长为10,最大分为34 2 = 36

感谢这位老哥分享思路剑指offer--剪绳子(动态规划+贪心算法)详解

//传进来的是绳子的长度
int CutRope(int n)
{
    int result = 0;
    if (n <= 1)
    {
        return 0;
    }
    if (n == 2)
    {
        return 2;
    }
    if (n == 3)
    {
        return 3;
    }
    //动态开辟数组
    int* temp = new int[n + 1];//数组索引从0开始
    //绳子多长(n多大),对应分割的最大乘积就存在数组对应下标所指向的值temp[n]
    temp[0] = 0;
    temp[1] = 0;
    temp[2] = 2;
    temp[3] = 3;
    /*
    我们不需要去考虑到底要分割成多少段求出来的乘积才是最大的,
    每次分割成都两段,这两段的乘积最大值已经在之前求出来并且存到了temp中对应的位置上了,
    我们只需要对比这几种分割(分成两段的不同情况,这两段最大的乘积都是多少)选出最大的,
    放到该长度n,在temp数组中的位置即可。
    例: 4 可以分为1 3,2 2 ,3 1 
    1、2、3分成的乘积最大值,在之前已经求出来了,最需要分成这两种的乘积即可。
    3 4 3 最大为 4 ,存进temp[4] = 4;
    
    */
    for (int i = 4; i <= 4; i++)
    {
        int max = 0;//保存当前长度乘积最大的。
        //循环计算出最大的
        for (int j = 1; j <= i / 2; j++)
        {
            if (max < temp[j] * temp[i - j])
            {
                max = temp[j] * temp[i - j];
            }
        }
        temp[n] = max;
    }
    result = temp[n];
    delete temp;
    return  result;
}
相关文章
|
2月前
|
存储 算法
深入了解动态规划算法
深入了解动态规划算法
64 1
|
2月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
5月前
|
算法 开发者 Python
惊呆了!Python算法设计与分析,分治法、贪心、动态规划...这些你都会了吗?不会?那还不快来学!
【7月更文挑战第10天】探索编程巅峰,算法至关重要。Python以其易读性成为学习算法的首选。分治法,如归并排序,将大问题拆解;贪心算法,如找零问题,每步求局部最优;动态规划,如斐波那契数列,利用子问题解。通过示例代码,理解并掌握这些算法,提升编程技能,面对挑战更加从容。动手实践,体验算法的神奇力量吧!
75 8
|
5月前
|
算法 Python
算法不再难!Python分治法、贪心、动态规划实战解析,轻松应对各种算法挑战!
【7月更文挑战第8天】掌握Python算法三剑客:分治、贪心、动态规划。分治如归并排序,将大问题拆解递归解决;贪心策略在每步选最优解,如高效找零;动态规划利用子问题解,避免重复计算,解决最长公共子序列问题。实例展示,助你轻松驾驭算法!**
72 3
|
1月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
46 2
|
2月前
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
93 2
动态规划算法学习三:0-1背包问题
|
2月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
78 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
2月前
|
算法
动态规划算法学习二:最长公共子序列
这篇文章介绍了如何使用动态规划算法解决最长公共子序列(LCS)问题,包括问题描述、最优子结构性质、状态表示、状态递归方程、计算最优值的方法,以及具体的代码实现。
161 0
动态规划算法学习二:最长公共子序列
|
2月前
|
存储 人工智能 算法
【算法——动态规划】蓝桥ALGO-1007 印章(C/C++)
【算法——动态规划】蓝桥ALGO-1007 印章(C/C++)
【算法——动态规划】蓝桥ALGO-1007 印章(C/C++)
|
2月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
140 0