常见算法思想——动态规划

简单介绍

  动态规划(Dynamic programming)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。 动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。

详细介绍

算法性质

1.最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
2.子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
3.无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。

算法步骤

1.划分:按照问题的特征,把问题分为若干阶段。注意:划分后的阶段一定是有序的或者可排序的。
2.确定状态和状态变量:将问题发展到各个阶段时所处的各种不同的客观情况表现出来。状态的选择要满足无后续性。
3.确定决策并写出状态转移方程:状态转移就是根据上一阶段的决策和状态来导出本阶段的状态。根据相邻两个阶段状态之间的联系来确定决策方法和状态转移方程。
4.边界条件:状态转移方程是一个递推式,因此需要找到递推终止的条件
即:【初始状态】→【决策1】→【决策2】→…→…→【决策n】→【结束状态】

注意:
  问题阶段;
  每个阶段的状态;
  相邻两个阶段之间的递归关系.

算法局限

  动态规划对于解决多阶段决策问题的效果是明显的,但是动态规划也有一定的局限性。首先,它没有统一的处理方法,必须根据问题的各种性质并结合一定的技巧来处理;另外当变量的维数增大时,总的计算量及存贮量急剧增大。因而,受计算机的存贮量及计算速度的限制,当今的计算机仍不能用动态规划方法来解决较大规模的问题,这就是“维数障碍”。

题目演示

题目描述

例:假设你正在爬楼梯,楼梯台阶级数为n级。每次你可以爬 1 或 2 级台阶。请问,你有多少种不同的方法可以爬完楼梯。
(注意:给定 n 是一个正整数)

题目分析

求解爬楼梯有多少种方式。如何使用DP(动态规划)方法解决,关键在于得出递推式。试想一下,每次不是走一步,就是走两步。那么第i次有多少种方式,是基于dp[i-1]+dp[i-2],就是决定于一个楼梯还剩两个或者还剩一个情况的方式的总和。

完整代码

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>

int climbStairs(int n) 
{
    int* dp = new int[n + 1];
    int i = 0;
    for (i = 0; i < 3 && i <= n; i++) 
        dp[i] = i;
    for (i = 3; i <= n; i++)
    {
        dp[i] = dp[i - 1] + dp[i - 2];
    }  
    return dp[n];
    delete[]dp; 
}

int main()
{
    int m,show; 
    printf("台阶级数为:");
    scanf("%d", &m);
    show = climbStairs(m); 
    printf("共有%d种方法走完台阶。\n", show);
    system("pause");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值