动态规划 + 示例

动态规划(英语:Dynamic programming,简称 DP),通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。(dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems.)
一般这些子问题很相似,可以通过函数关系式递推出来这个相似的子问题的结构。然后动态规划就致力于使每个子问题只被解决一次,减少重复计算,比如斐波那契数列就可以看做入门级的经典动态规划问题。所以动态规划的核心思想就是拆分出重复子问题,记忆答案,减少重复计算。
动态规划的本质是一个状态机,从初始状态开始进行有向无环的跳转,最终求得最终解。状态转移方程完美诠释了状态机中状态跳转的概念

示例:M级超级台阶
程序展示(自底向上递推)

#include "iostream"
using namespace std;
 
int n;
int m,dp[3];
int main(){
    cin>>n;
    for (int i = 1; i <=n ; ++i) {
        cin>>m;
        dp[0] = dp[1] = 1;
        if(m<2){
            break;
        }
        for(int j=2;j<m;j++){
            dp[j%3] = dp[(j-1)%3]+dp[(j-2)%3];//这里使用滚动数组来优化空间
        }
        cout<<dp[(m-1)%3]<<endl;
    }
    return 0;
}

程序展示(自顶向下记忆话搜索)

#include "iostream"
using namespace std;
 
int n;
int m,dp[41];
int dfs(int n);
int main(){
    cin>>n;
    for (int i = 1; i <=n ; ++i) {
        cin>>m;
        cout<<dfs(m)<<endl;
    }
    return 0;
}
 
int dfs(int n){
    if(n == 1||n == 2){
        return 1;
    }
    if(dp[n]){
        return dp[n];
    }
    dp[n] = dfs(n-1) + dfs(n-2);
    return dp[n];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值