Day5 动归

动态规划与优化:从Fibonacci函数看算法效率
文章探讨了动态规划在解决Fibonacci函数中的应用,涉及空间优化、时间复杂度分析以及如何通过构建DAG图来优化重叠搜索。讨论了动归在将非P问题转化为P问题中的作用,并举例了排列和组合问题在动态规划中的体现。

优化算法:

动归:重叠优化

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

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

动态规划:空间优化

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

空间优化: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 ]
]

有两张表,一张表记录工号、白晚班、排班上班时间和下班时间(例如:白班是2025/3/19 8:30到17:30;晚班是2025/3/18 20:30到2025/3/19 5:30);另一张表记录工号、刷卡时间。请编写一段SQL,将记录刷卡时间的归卡对应到另一张排班表中。上述需求请考虑如下情况:有一笔刷卡是晚班刷卡上班是2025/3/18 20:30,下班是2025/3/19 9:30,但是2025/3/18排班是晚班,2025/3/19排班是白班。请结合如上需求修改如下SQL,提高执行效率:WITH A AS (SELECT A.PSN_ID, A.PSN_SEG_SEGMENT_NO, A.CDAY, A.INTIME, A.OUTTIME, A.DAYHOURS, A.SHIFT_ID, C.SHIFT_NAME FROM HCP.HR_CARDING A LEFT JOIN HR_SHIFT C ON A.SHIFT_ID = C.SHIFT_ID AND A.PSN_SEG_SEGMENT_NO = C.SEG_SEGMENT_NO), B AS (SELECT DECODE (SUBSTR (FGT08, 3, 1),'1', '1','2', '2',SUBSTR (FGT08, 3, 1)) STATUS, T.* FROM FINGER5.FGT_FILE T WHERE SUBSTR(FGT08,3,1) IN ('1', '2') ) SELECT A.PSN_ID, A.PSN_SEG_SEGMENT_NO, A.CDAY, A.INTIME, A.OUTTIME, A.DAYHOURS, A.SHIFT_ID, A.SHIFT_NAME, MAX (CASE WHEN B.STATUS = '1' THEN B.FGT02 END) INACTUAL, MAX (CASE WHEN B.STATUS = '2' THEN B.FGT02 END) OUTACTUAL FROM A LEFT JOIN B ON B.FGT10 = HCP.SF_BPM_ID_GET (A.PSN_ID, 9) AND (CASE WHEN A.SHIFT_NAME LIKE '%白班%' AND B.STATUS IN ('1', '2') AND A.CDAY = TRUNC (B.FGT02) THEN 1 WHEN A.SHIFT_NAME LIKE '%晚班%' AND B.STATUS = '1' AND A.CDAY = TRUNC (B.FGT02) THEN 1 WHEN A.SHIFT_NAME LIKE '%晚班%' AND B.STATUS = '2' AND A.CDAY = TRUNC (B.FGT02)-1 THEN 1 END)=1 WHERE A.PSN_ID = '11130301' AND B.STATUS IN ('1', '2') GROUP BY A.PSN_ID, A.PSN_SEG_SEGMENT_NO, A.CDAY, A.INTIME, A.OUTTIME, A.DAYHOURS, A.SHIFT_ID, A.SHIFT_NAME;
03-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值