Day5 动归

优化算法:

动归:重叠优化

减治:无效优化,一定是有序的

从熵的角度开始理解->混乱

动态规划:空间优化

 时空优化:时间优化:减治

空间优化:1.先序:

for:滚动数组

dfs

bfs

2.后序:仅对重叠点做优化

   

var fib = function(n) {
    if(n == 0) return 0;
    if(n == 1) return 1;
    
    //状态
    const dp = new Map()
    dp.set(0,0)
    dp.set(1,1)
   
    //入度:先序遍历要统计入度,入度的意义代表该点依赖于多少个点,当一个状态点接收到一个点的值,那么入度-1
    const indeg = new Array(n+1).fill(2)
    indeg[0] = 0
    indeg[1] = 0

    //队列:队列中的状态点的值已经求出来了
    const queue = [0,1]

    while(queue.length){
        //出队
        const x = queue.shift()

        //目标
        if(x === n){
            return dp.get(x) 
        }
        //扩展:0的邻接节点为2,其他的点邻接节点为x+1
        const next = x === 0 ? [2] : [x+1,x+2] //next代表x的邻接节点
        for(let y of next){
            if(y > n) continue
            dp.set(y,(dp.get(y)||0) + dp.get(x))
            dp[y] += dp[x]  //y已经接收到x传来的值了,注意这里的递推公式是求和,你能想出什么递推公式呢?
            indeg[y]--      //y所依赖的点的个数-1   
            if(indeg[y] === 0) queue.push(y)  //y不依赖于任何点,y的值求出来了,可以入队
        }

        //先序空间优化:当一个状态节点将其值传递给后序节点之后,就废弃了
        dp.delete(x) 
    }
};

3.dfs先序空间优化

var fib = function(n) {
    if(n == 0) return 0
    if(n == 1) return 1
    //状态:空间优化
    const dp = new Map()
    dp.set(0,0)
    dp.set(1,1)

    //入度统计
    const indeg = new Array(n+1).fill(2)
    indeg[0] = 0
    indeg[1] = 0

    //队列:队列中的状态点的值已经求出来了
    const begin = [0,1]

    const dfs = (x) => {
        //目标
        if(x === n) return
        
        //扩展
        const next = x === 0 ? [2] : [x+1,x+2] //next代表x的邻接节点
        for(let y of next){ 
            if(y > n) continue
            dp.set(y,(dp.get(y)||0) + dp.get(x)) //y接受到x传来的值了
            indeg[y]--      //y所依赖的点的个数-1   
            if(indeg[y] === 0) dfs(y)  //y不依赖于任何点,y的值求出来了,可以入队
        }
        //先序空间优化:当一个状态节点将其值传递给后序节点之后,就废弃了
        dp.delete(x) 
    }

    for(let x of begin) dfs(x)

    return dp.get(n)
};

动归->时间复杂度分析->五大类型

重叠搜索:所有的数据结构从优化的角度来讲,最终都要转换为dag.

不可解问题:非p问题

可解问题:p问题

动归意义:非p问题转换为p问题

 排列问题:是动态规划  1.排列;2.博弈;(非连续性的)

组合问题:也是动态规划 1.组合;2.选择; 3.分割 23定序, 1无序

有序用来串联:1.排列有序;2.博弈换序;3.组合无序

这五种类型,建立dag图最重要的方式

var fib = function(n){
    //边界
    if(n === 0 || n === 1) return [[n]]
    
    const res = []
    const ans = []
    const dfs = (x) =>{
        if(x > n){
            if(ans[ans.length-1] == n) res.push(ans.slice())
            return 
        }
        const next = x === 0 ? [2] : [x+1,x+2] //next代表x的邻接节点
        ans.push(x)
        for(let y of next) dfs(y)
        ans.pop()
    }
    dfs(0)
    dfs(1)
    return res 
}

//打印结果
console.log(fib(4))
//输出结果
[
  [ 0, 2, 3, 4 ],
  [ 0, 2, 3, 4 ],
  [ 0, 2, 4 ],
  [ 0, 2, 4 ],
  [ 1, 2, 3, 4 ],
  [ 1, 2, 3, 4 ],
  [ 1, 2, 4 ],
  [ 1, 2, 4 ],
  [ 1, 3, 4 ],
  [ 1, 3, 4 ]
]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值