动态规划学习总结1 动态规划入门理解

1.动态规划的本质: 递归

2.原问题(N) - >子问题(N-1)->原问题(N)

3.最优子结构:

​ - 子问题最优决策可导出原问题最优决策

​ - 无后效性

4.重叠子问题:

​ - 去冗余

​ - 空间换时间 (时空复杂度的分析)

  1. 问题共性:

​ - 套路:最优、最大、最小、最长、计数

​ - 离散问题:整数01背包问题

​ - 最优子结构。N-1可以推导出N

6.基本步骤

​ 1.设计暴力算法,找到冗余

​ 2.设计存储状态(一维、二维、三维数组甚至用Map)

​ 3.递归式(状态转移方程)

​ 4.自底向上计算最优解(编程方式)

例题1. leetcode 198 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4 。
输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
     偷窃到的最高金额 = 2 + 9 + 1 = 12 。

接下来以这个题为例子入手:

按照步骤一步一步来:

1⃣️. 设计暴力算法,找到冗余. 在这里通过递归进行暴力求解

我们可以从后往前来看

2⃣️设计存储状态(下面的暴力算法不用,后面的动态规划做法。开辟了一个一维数组保存中间结果)

3⃣️递归式 状态转移方程

4⃣️自底向上计算最优解。(写法3)

假如从最后一家开始抢,对于每一家店nums[i],小偷都有两种选择 抢和不抢

若是抢,由于不能抢连续的两家店,则小偷无法抢nums[i-1]; nums[i] + nums[i-2]

若是不抢,则金额可以是 nums[i-1]

首先我们可以写一个暴力递归版本 时间复杂度O(2^n) 空间复杂度O(1)

写法1 暴力算法(超时)

class Solution {
    public int solve(int idx,int[] nums){
        //判断边界条件
         if(idx < 0 ) return 0;
         
        //选择抢nums[idx]的方式
        int method1 = nums[idx] + solve(idx-2,nums);
        //选择不抢nums[idx]的方式
        int method2 = solve(idx-1,nums);
        
        //从两个方式中选择最大的那个方式
        int res = Math.max(method1,method2);
        return res;
    }
    

    public int rob(int[] nums) {
           return solve(nums.length-1,nums); 
    }
}

下面画图分析一下递归过程


WX20190227-234327@2x.png

​ 我们可以发现 在执行递归的过程中 有许多调用是重复的,这样就会使得时间开销大大增大,以指数级别增长

​ 为了提高时间效率,我们可以采用牺牲部分空间的方式,即可以开辟出来一份空间来保存这些重复的中间结果,

​ 使得这些中间结果只计算一次.

​ 对于这道题我们可以开辟一个数组dp[]来保存中间结果 dp[i]表示到第i个店时已经抢到的最优金额

​ 从后往前搜索的版本. 时间复杂度O(n) 空间复杂度O(n)

写法2:

class Solution {
    
    private int []dp;
    
    public int solve(int idx,int[] nums){
        
        //边界条件
        if(idx < 0){
            return 0;
        }
        
        //记忆化搜索
        if(dp[idx] != -1){
            return dp[idx];
        }
        
    
        //抢idx
        int method1  = nums[idx] + solve(idx-2,nums);
        //不抢idx
        int method2 = solve(idx-1,nums);

        dp[idx] =  Math.max(method1,method2);
        
        return dp[idx];
        
    }
    

    public int rob(int[] nums) {
        dp = new int[nums.length];
        
        //进行初始化
        for(int i = 0; i < dp.length;i++){
            dp[i] = -1;
        }
        
        return solve(nums.length-1,nums);
       
        
    }
}

写法3:

从前往后搜索的版本. 时间复杂度O(n) 空间复杂度O(n)

class Solution{ 
    private int[] dp;
    
    public int solve(int idx,int [] nums){
        
        if(idx >= nums.length){
            return 0;
        }
        
        if(dp[idx]!= -1){
            return dp[idx];
        }
        
        //选择第一个
        int method1 = nums[idx] + solve(idx+2,nums);
        //不选择第一个
        int method2 = solve(idx+1,nums);
        
        
        dp[idx] = Math.max(method1,method2);
        
        return dp[idx];
       
    }

    public int rob(int[]  nums){
        dp = new int [nums.length];
        for(int i=0;i<nums.length;i++){
            dp[i] = -1;
        }
        
        return solve(0,nums);
        
        
    }  
}


WX20190228-003737@2x.png

作者:lhsjohn 喜欢的话谢谢点赞~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容