最新剑指Offer——动态规划算法_算法动态规划,重要概念一网打尽

总结

阿里十分注重你对源码的理解,对你所学,所用东西的理解,对项目的理解。

最新阿里蚂蚁金服四面(已拿offer)Java技术面经总结

最新阿里蚂蚁金服四面(已拿offer)Java技术面经总结

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

最新阿里蚂蚁金服四面(已拿offer)Java技术面经总结

2.问题中的状态必须满足无后效性。

所谓无后效性是指:“下一时刻的状态只与当前状态有关,而和当前状态之前的状态无关,当前状态是对以往决策的总结”。

动态规划算法的设计

两种方法:

自顶向下(又称记忆化搜索、备忘录):基本上对应着递归函数实现,从大范围开始计算,要注意不断保存中间结果,避免重复计算

自底向上(递推):从小范围递推计算到大范围

动态规划的重点

递归方程+边界条件

爬楼梯问题

一个人每次只能走一层楼梯或者两层楼梯,问走到第80层楼梯一共有多少种方法。

设DP[i]为走到第i层一共有多少种方法,那么DP[80]即为所求。很显然DP[1]=1, DP[2]=2(走到第一层只有一种方法:就是走一层楼梯;走到第二层有两种方法:走两次一层楼梯或者走一次两层楼梯)。同理,走到第i层楼梯,可以从i-1层走一层,或者从i-2走两层。很容易得到:

递推公式:DP[i]=DP[i-1]+DP[i-2]

边界条件:DP[1]=1   DP[2]=2

(a)自顶向下的解法:

long long dp[81] = {0};/*用于保存中间结果否则会重复计算很多重复的子问题*/
long long DP(int n)
{
    if(dp[n])
        return dp[n];
    if(n == 1)
        return 1;
    if(n == 2)
        return 2;
    dp[n] = DP(n-1) + DP(n-2);
    return dp[n];
}  

(b)自底向上的解法:

int i;  
long long dp[81]; /* 注意当n超过75时,结果值将超过int范围 */  
dp[1] = 1;  
dp[2] = 2;  
for(i=3; i <= 80; i++)  
    dp[i] = dp[i-1] + dp[i-2];

最长上升子序列

对于序列:4 1 2 24,它的最长上升子序列是1 2 4,长度为3。

对于序列:4 2 4 25 6,它的最长上升子序列是2 4 5 6,长度为4。

设a[i]表示原序列,设DP[i]表示以第i个数结尾的最长上升序列的长度,那么很显然想导出DP[i]的值,需要在DPk中找出满足a[k]<a[i]最大的一项。假设第kk项是我们找到的答案,那么第i个数就可以接在第kk个数之后,成为以第i个数结尾的最长升序列。如果没有找到答案,换言之第i个数比前面的数都要小,那么DP[i]=1,也即生成了从自己开始又以自己结尾的最长升序列。综上,我们很容易得出:

递推公式:DP[i]=max(DP[k]+1,DP[i])  1<=k<i

边界条件:DP[i]=1                   1<=i<=n

算法复杂度为O(n^2)

void RiseSequence(int Array[], int num)  
{  
#define MAX_LENGTH  30  
    struct  
    {  
        int SequenceValue;  /* max length ending with this num */  
        int PreviousIndex;  /* record the previous number */  
    }ArrayInfo[MAX_LENGTH], temp;  
    int i;  
    for(i = 0; i < num; i++)  
    {  
        int j;  
        ArrayInfo[i].SequenceValue = 1;  
        ArrayInfo[i].PreviousIndex = -1;  
        for(j = 0; j < i; j++)  
        {  
            if(Array[j] < Array[i] && (ArrayInfo[j].SequenceValue + 1 > ArrayInfo[i].SequenceValue))  
            {  
                ArrayInfo[i].SequenceValue = ArrayInfo[j].SequenceValue + 1;  
                ArrayInfo[i].PreviousIndex = j;  
            }  
        }  
    }  
    temp.SequenceValue = ArrayInfo[0].SequenceValue;  
    for(i = 1; i < num; i++)  
    {  
        if(temp.SequenceValue < ArrayInfo[i].SequenceValue)  
        {  
            temp.SequenceValue = ArrayInfo[i].SequenceValue;  
            temp.PreviousIndex = i;  
        }  


**前端面试题汇总**

![](https://img-blog.csdnimg.cn/img_convert/8087f8c06b129975b3b7be228aa41f0d.png)

**JavaScript**

![](https://img-blog.csdnimg.cn/img_convert/7796de226b373d068d8f5bef31e668ce.png)

**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

**性能**

![](https://img-blog.csdnimg.cn/img_convert/d7f6750332c78eb27cc606540cdce3b4.png)

**linux**

![](https://img-blog.csdnimg.cn/img_convert/ed368cc25284edda453a4c6cb49916ef.png)

**前端资料汇总**

![](https://img-blog.csdnimg.cn/img_convert/6e0ba223f65e063db5b1b4b6aa26129a.png)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值