【C++动态规划学习总结】

本文介绍了动态规划的概念,作为对暴力递归的优化,它通过存储计算结果避免重复计算。文章通过详细解释机器人走路问题,展示了动态规划的应用,包括机器人在有限位置路上的移动策略。此外,还讨论了一个涉及玩家拿取数组元素的游戏,分析了获胜策略。总结部分对动态规划的运用进行了提炼。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.动态规划:初识

动态规划(英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

实际上是对暴力递归的一种优化,把已经计算过的信息保存起来,下次要用时不用重复计算,并且通过求解动态数组的方式代替了函数的递归调用。

第一步优化在于对计算结果的存储,避免重复计算。可以优化成下面描述的记忆化搜索方法。
第二步优化在于对递归函数调用的优化,直接从bace case 反推,而不是从上往下调用。


2.例子:

1.1机器人走路问题

机器人在有N个位置的路上走,开始机器人在M位置,机器人可左右移动,到1位置时只能右移,到N位置时只能左移,机器人从起始位置M到目标位置P,共走K步,求移动的方法数
参靠左神代码编写:

#include <iostream>
#include <vector>
using namespace std;

/* 原始暴力递归
 * N:总位置数   cur:当前位置    rest:剩余步数  aim:目标位置
 * 返回: 从cur到 aim 的方法数
 */
int way1(const int N, int rest, int cur, const int aim)
{
   
    //第一步,返回边界
    if (rest == 0) // base case
    {
   
        return (cur == aim ? 1 : 0);
    }
    //第二步,看当前位置的分指数个数(分普通情况和特殊情况)
    //特殊情况,来到最左边时
    if (cur == 1)
    {
   
        return way1(N, rest - 1, 2, aim);
    }
    //来到最右端时
    if (cur == N)
    {
   
        return way1(N, rest - 1, N - 1, aim);
    }
    //来到中间位置时
    return way1(N, rest - 1, cur + 1, aim) + way1(N, rest - 1, cur - 1, aim);
}

//傻缓存法改进(记忆化搜素)
int way2(const int N, int rest, int cur, const int aim, vector<vector<int>> &dp) //注意传引用
{
   
    if (dp[cur][rest] != -1)
    {
   
        return dp[cur][rest];
    }
    if (rest == 0) //边界条件 步数走完当前值到达目标点时有一种方法,否则无
    {
   
        return cur == aim ? 1 : 0;
    }
    //如果此条信息计算过,则直接返回dp数组里存的值

    int ret = 0; //存返回值,用来给dp数组赋值
    if (cur == 1)
    {
   
        ret = way2(N, rest - 1, 2, aim, dp);
    }
    else if (cur == N)
    {
   
        ret = way2(N, rest - 1, N - 1, aim, dp);
    }
    else
    {
   
        ret = way2(N, rest - 1, cur - 1, aim, dp) + way2(N
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值