算法【动态规划】 | 【01】二维表结构

一、问题解决思路:

先尝试用递归写法 -> 建立数组讲数据缓存到数组中 -> 建立表格结构优化

- 先确定限界条件;
- 根据设定变量构建表格;
- 在根据调用函数需要的状态来确定表格中获取结果的位置【以下图中的★】
- 根据限界条件先将部分表格填充获取去除;
- 在根据其他条件对表格进行填充,至填到★即结果;

二、问题一:

1、问题描述

当在n个位置中,从起始位置到结尾位置必须走k步到达终点,一共有几种走法?

2、图文解析

在这里插入图片描述

3、递归代码

/*----------------------------------------------------------------------
	> File Name: base.cpp
	> Author: Jxiepc
	> Mail: Jxiepc
	> Created Time: Thu 17 Mar 2022 08:41:03 AM CST
----------------------------------------------------------------------*/

#include <iostream>
#include <vector>


/**
 * @param e: 列表长度
 * @param t: 目标
 * @param rest: 剩余步数
 * @param cur: 当前位置
 * */
int solve(int e, int t, int rest, int cur) {
    if(rest == 0) {
        return cur == t ? 1 : 0; 
    }
    if(cur == 1) {
        solve(e, t, rest-1, 2);
    }

    if(cur == e) {
        solve(e, t, rest-1, e-1);
    }

    return solve(e, t, rest-1, cur+1) + solve(e, t, rest-1, cur-1); 
}

int main(int argc, char* argv[])
{
    int step = 4;
    int target = 4;
    int cur = 2;

    std::cout << solve(5, target, step, cur) << std::endl;
    return 0;
}

4、动态规划代码

/*----------------------------------------------------------------------
	> File Name: dynamicBase.cpp
	> Author: Jxiepc
	> Mail: Jxiepc
	> Created Time: Fri 18 Mar 2022 09:14:32 PM CST
----------------------------------------------------------------------*/

#include <iostream>


/**
 * @param e: 列表长度
 * @param t: 目标
 * @param rest: 剩余步数
 * @param cur: 当前位置
 * @param arr: 存储是数据信息
 * */

int solve(int e, int t, int rest, int cur, int arr[][6]) {

    if(arr[rest][cur] != -1) {
        return arr[rest][cur];
    }
    if(rest == 0) {
        arr[rest][cur] = cur == t ? 1 : 0; 
    }else if(cur == 1) {
        arr[rest][cur] = solve(e, t, rest-1, 2, arr);
    }else if(cur == e) {
        arr[rest][cur] = solve(e, t, rest-1, e-1, arr);
    }else {
        arr[rest][cur] = solve(e, t, rest-1, cur+1, arr) + solve(e, t, rest-1, cur-1, arr); 
    }
    return arr[rest][cur];
}


int main(int argc, char* argv[])
{
    
    int arr[6][6];
    for(int i=0; i<6;++i) {
        for(int j=0; j<6; ++j) {
            arr[i][j] = -1;
        }
    }
    int step = 4;
    int target = 4;
    int cur = 2;

    int rt = solve(5, targert, step, cur, arr);
    std::cout << arr[step][target];
    return 0;
}

二、问题二

1、问题描述

题中给出数组arr = [3,100,4,50],A、B两人分别从数组中取出数组,只能从最左或者最右取出数值,当列表取完后,比较A、B
两个的累加和判度最大的一方;

2、图文解析

在这里插入图片描述

3、递归代码

/*----------------------------------------------------------------------
	> File Name: base.cpp
	> Author: Jxiepc
	> Mail: Jxiepc
	> Created Time: Sat 19 Mar 2022 03:40:35 PM CST
----------------------------------------------------------------------*/

#include <vector>
#include <iostream>


/**
 * 玩家A、B:A先取列表中【最左或者最右的数,最大的】,在轮到B取;
 * 后续判断两者取到的数最大
 * */
int f(std::vector<int> vc, int l, int r);


int s(std::vector<int> vc, int l, int r) {
    if(l == r)
        return 0;
    return f(vc, l+1, r) > f(vc, l, r-1) ? 
        f(vc, l+1, r) : f(vc, l, r-1);
}

int f(std::vector<int> vc, int l, int r) {
    if(l == r)
        return vc[l];

    return vc[l] + s(vc, l+1, r) > vc[r] + s(vc, l, r-1) ? 
        vc[l] + s(vc, l+1, r) : vc[r] + s(vc, l, r-1);
}


int solve(std::vector<int> vc) {

    return f(vc, 0, vc.size() -1) > s(vc, 0, vc.size()-1) ? 
        f(vc, 0, vc.size() -1) : s(vc, 0, vc.size()-1);
}

int main(int argc, char* argv[])
{
    std::vector<int> vc = {3, 100, 4, 50};
    std::cout << solve(vc) << std::endl;
    return 0;
}

4、动态规划代码

/*----------------------------------------------------------------------
	> File Name: dynamicBase.cpp
	> Author: Jxiepc
	> Mail: Jxiepc
	> Created Time: Sat 19 Mar 2022 04:14:32 PM CST
----------------------------------------------------------------------*/

#include <iostream>
#include <vector>

int solve(std::vector<int> vc) {
    if(vc.empty())
        return 0;
    int len = vc.size();
    int f[len][len] = {0};
    int s[len][len] = {0};

    for(int i=0; i<len; ++i) {
        f[i][i] = vc[i];
    }

    int row = 0, col=1;
    while(col < len) {
        int i = row;
        int j = col;
        while(i < len && j < len) {
            /* f的位置是选择列表中的值以及s表中的下一行或者前一列的值 */
            f[i][j] = (vc[i] + s[i+1][j]) > (vc[j] + s[i][j-1]) ? 
                (vc[i] + s[i+1][j]) : (vc[j] + s[i][j-1]);

            s[i][j] = f[i + 1][j] < f[i][j-1] ? 
                f[i + 1][j] : f[i][j-1];
            std::cout << "f:" << f[i][j] << " " << i << "-" << j << std::endl;
            std::cout << "s:" << s[i][j] << " " << i << "-" << j << std::endl;
            j++;
            i++;
        }
        col++;
    }
    return f[0][len-1] > s[0][len-1] ? f[0][len-1] : s[0][len-1];
}

int main(int argc, char** argv){
    std::vector<int> vc = {3, 100, 4, 50};
    std::cout << solve(vc) << std::endl;

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 自适应动态规划算法是一种灵活的算法,可以根据问题的性质自动调整算法的参数,以获得更高的效率和更好的结果。下面将介绍如何用Matlab实现自适应动态规划算法程序。 首先,我们需要定义问题的状态和决策。状态是问题的规模和相关信息,决策是在给定状态下要做的选择。根据问题的不同,状态和决策的定义也会不同。 然后,我们需要定义递归函数。递归函数用于描述问题的最优子结构,即当前状态的最优解和子问题的最优解之间的关系。在函数中,我们通过递归调用自身来解决子问题,并使用动态规划的思想将中间结果保存起来,以避免重复计算。 接下来,我们需要定义状态转移方程。状态转移方程描述了当前状态如何由前一状态转移而来。在自适应动态规划算法中,我们需要根据问题的性质来选择合适的状态转移方程。通常情况下,状态转移方程是通过对问题进行建模,得到的一个函数达式。 最后,我们需要定义边界条件。边界条件指定了问题的最小规模下的解,即递归函数的终止条件。在自适应动态规划算法中,边界条件通常是问题规模达到某个阈值时,使用其他算法或方法来求解。 综上所述,用Matlab实现自适应动态规划算法程序需要依次完成定义问题的状态和决策、定义递归函数、定义状态转移方程和定义边界条件这四个步骤。在实际编程中,我们还需要考虑输入输出的处理、中间结果的保存和查找等问题。通过这些步骤,我们可以使用Matlab编写一个自适应动态规划算法程序,用于解决各种复杂的优化问题。 ### 回答2: 自适应动态规划算法是一种自适应的优化算法,它在动态规划的基础上结合了贪心算法和回溯算法,能够根据问题的特性和特定场景来灵活调整算法的策略。 在MATLAB中实现自适应动态规划算法,可以按照以下步骤进行: 1. 定义问题的状态和状态转移方程:根据具体的问题,确定问题的状态变量和状态转移方程。通常状态可以用一个或多个变量示,状态转移方程描述了状态之间的关系。 2. 初始化动态规划:根据问题的状态数目,创建一个动态规划,用于存储中间结果。初始化中的元素,通常将无效值或者无穷大值赋给中的某些位置,以便在计算过程中进行比较和更新。 3. 确定优化策略:根据问题的特点和目标,确定算法的优化策略。可以考虑采用贪心策略或者回溯策略,或者结合二者,根据具体场景来决策。 4. 实现动态规划算法:根据状态变量、状态转移方程和优化策略,编写MATLAB程序来实现动态规划算法。通常使用循环结构来计算每个状态的值,并根据优化策略进行比较和更新。 5. 返回最优解:根据动态规划中计算得到的最优值,回溯得到最优解。可以通过保存路径或者关联格的方式来记录每个状态的选择,从而得到最优解。 在MATLAB中实现自适应动态规划算法时,需要注意程序的效率和运行时间。可以通过优化算法的策略、使用矩阵运算、避免重复计算等方式来提高算法的性能。 总的来说,实现自适应动态规划算法需要根据具体问题进行适当的调整和优化,灵活运用贪心算法和回溯算法,通过动态规划来存储中间结果,并根据优化策略来计算每个状态的值,最终得到最优解。 ### 回答3: 自适应动态规划算法是一种基于动态规划思想的算法,在处理复杂问题时具有很高的效率和灵活性。通过自适应的方式,可以根据问题的特点动态调整算法的具体实现,以求得更优的解。 在MATLAB中实现自适应动态规划算法,可以按照以下步骤进行: 1. 定义问题的状态:根据具体问题,定义问题的状态,并将其示为一个二维数组。例如,对于最长公共子序列问题,可以定义状态为dp(i,j),示字符串A和B前i和j个字符的最长公共子序列的长度。 2. 初始化边界条件:根据问题的特点,初始化边界条件,并将其存储在状态数组中。例如,在最长公共子序列问题中,可以将dp(i,0)和dp(0,j)均初始化为0,示空字符串与任意字符串的最长公共子序列长度均为0。 3. 确定状态转移方程:根据问题的特点,确定状态之间的转移关系,并将其示为状态转移方程。例如,在最长公共子序列问题中,状态转移方程为dp(i,j) = dp(i-1,j-1) + 1,当A(i) = B(j),否则为max(dp(i-1,j), dp(i,j-1))。 4. 根据状态转移方程,利用循环结构动态计算状态数组中的每一个元素。可以使用两层循环依次计算dp(i,j)的值,并存储在状态数组中。 5. 根据状态数组的最终结果,得到问题的最优解。例如,在最长公共子序列问题中,可以通过查找状态数组dp中的最后一个元素dp(m,n)来获取问题的最长公共子序列长度。 通过上述步骤,可以在MATLAB中实现自适应动态规划算法。根据具体问题的不同,可以灵活调整算法的实现,以达到更好的性能和效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jxiepc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值