动态规划

动态规划:通常基于一个递推公式及一个或多个初始状态当前子问题的解将由上一个子问题的解推出

基本思想:要解决一个给定的问题,我们需要解决其不同部分(即解决子问题),再合并子问题的解以得出原问题的解,通常子问题非常相似,为此动态规划视图只解决每个子问题一次,从而减少计算量,一旦某个给定子问题的解已经算出来,则将其记忆储存,以便下次需要同一个子问题解值时直接查表

1》斐波那契数列

方法一:递归调用

function feibonaqi(n){

return n<2?n:feibonaqi(n-1)+feibonaqi(n-2);

}

console.log(feibonaqi(5));//5  最多能达到40左右

尾调调用斐波那契数代码改进

function feibonaqie(n,ac1=1,ac2=1){

return n<2?ac2:feibonaqie(n-1,ac2,ac1+ac2);

}

console.log(feibonaqie(1000));//可以输入数字大概到1000

方法二:备忘录算法

var map=new Map();

function feibonaqi(n){

if(n<2) return n;

if(map.has(n)){

return map.get(n);

}

var value=feibonaqi(n-1)+feibonaqi(n-2);

map.set(n,value);

return value;

}

 console.log(feibonaqi(5));//5

方法三:

function feibonaqi(n){

if(n<2) return n;

var a=1,b=1;

var temp=a+b;

for(var i=3;i<=n;i++){

temp=a+b;

a=b;

b=temp;

}

return temp;

}

console.log(feibonaqi(5));//5 能达到1000

2》爬楼梯问题

方法一:递归求解,时间复杂度0(2^n)

根据递归公式

f(n)=f(n-1)+f(n-2); f(1)=1; f(2)=2

function getways(n){

if(n<1) return 0;

if(n==1) return 1;

if(n==2) return 2;

return getways(n-1)+getways(n-2);

}

var n=4;

console.log(getways(n));//5

方法二:把重复的值记录下来使用备忘录算法,时间复杂度0(n),空间复杂度0(n)

var map=new Map();

function getways(n){

if(n<0) return 0;

if(n==1) return 1;

if(n==2) return 2;

if(map.has(n)){

return map.get(n)

}

var value=getways(n-1)+getways(n-2);

map.set(n,value);

return value;

}

console.log(getways(4));

方法三:正常思路从下往上走,可以看出每次迭代只需要前两次迭代的数据,时间复杂度O(n),但是空间复杂度0(1)

function getways(n){

if(n<0) return 0;

if(n==1) return 1;

if(n==2) return 2;

var a=1,b=2;

var temp=a+b;

for(var i=3;i<=n;i++){

temp=a+b;

a=b;

b=temp;

}

return temp;

}

console.log(getways(1000));

3》求连续子数组中最大和

思路:动态规划

遍历数组,遇到负的和则放弃之前的结果,重新积累,这期间保留最大值

用max记录最终返回的最大和,用curmax记录累加值

对于数值中一个数arr[i],若其左边的累加和非负,那么加上arr[i]

判断此时的curmax是否大于max,若大于此时的max,则用max记录下来

function FindGreateSum(arr){

var len=arr.length;

var curmax=0;

var max=0;

var start=0;

var end=0;

//数组中正负数都有

for(var i=0;i<len;i++){

curmax+=arr[i];

if(curmax<0){

curmax=0;

}

if(curmax>max){

max=curmax;

}

}

return max;

}

var arr=[2,4,-7,5,2,-1,2,-4]

console.log(FindGreateSum(arr));

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值