LeetCode|動(dòng)態(tài)規(guī)劃入門三題

一的烁、爬樓梯

假設(shè)你正在爬樓梯绎橘。需要 n 階你才能到達(dá)樓頂诉位。
每次你可以爬 1 或 2 個(gè)臺(tái)階骑脱。你有多少種不同的方法可以爬到樓頂呢?
注意:給定 n 是一個(gè)正整數(shù)苍糠。

示例 1:

輸入: 2
輸出: 2
解釋: 有兩種方法可以爬到樓頂叁丧。

  1. 1 階 + 1 階
  2. 2 階

示例 2:

輸入: 3
輸出: 3
解釋: 有三種方法可以爬到樓頂。

  1. 1 階 + 1 階 + 1 階
  2. 1 階 + 2 階
  3. 2 階 + 1 階

解題思路

本題是動(dòng)態(tài)規(guī)劃里面最簡單的題目了岳瞭,印象中第一次見到這個(gè)題目還是在藍(lán)橋杯的練習(xí)題中拥娄。
雖然本篇是動(dòng)態(tài)規(guī)劃的入門文章,但是我并不會(huì)說任何書面上寫的動(dòng)態(tài)規(guī)劃算法的定義寝优。這是因?yàn)閯?dòng)態(tài)規(guī)劃的概念還是很復(fù)雜的条舔,看完動(dòng)態(tài)規(guī)劃算法的思路和特性估計(jì)你就被動(dòng)態(tài)規(guī)劃嚇到了。
關(guān)于動(dòng)態(tài)規(guī)劃的定義乏矾,我只說一句個(gè)人看法——?jiǎng)討B(tài)規(guī)劃求的是全局最優(yōu)解孟抗。全局意味著動(dòng)態(tài)規(guī)劃是要全盤考慮問題的。話不多說钻心,我們先從題目解答中開始體會(huì)凄硼。

本題中,我們看到捷沸,爬1階梯只有1種方法摊沉,爬2階梯有2種方法。那我們就能想到痒给,爬3階梯有3種说墨,這是因?yàn)榕?階等于爬2階的基礎(chǔ)上再爬1階。同理爬4階等于在3階的基礎(chǔ)上爬1階和2階的基礎(chǔ)上爬2階苍柏;

這種“站在巨人的肩膀上”的思路就是動(dòng)態(tài)規(guī)劃的思想尼斧。

實(shí)現(xiàn)代碼

首先我們能想到的是使用遞歸的方法。遞歸方法跟我們上面的思路正好反過來试吁。遞歸的思路是爬n階樓梯的方式等于爬n-1階樓梯的次數(shù)加上n-2階樓梯的次數(shù)棺棵。但是遞歸方法不會(huì)保存計(jì)算結(jié)果,導(dǎo)致有很多重復(fù)的計(jì)算,因此超時(shí)也就不可避免了烛恤。

1. 遞歸
class Solution {
    public int climbStairs(int n) {
        if(n==1) return 1;
        if(n==2) return 2;
        return climbStairs(n-1)+climbStairs(n-2);
    }
}

運(yùn)行結(jié)果:超時(shí)

2. 動(dòng)態(tài)規(guī)劃

動(dòng)態(tài)規(guī)劃的整體思路跟遞歸很像母怜,但是會(huì)通過一個(gè)dp數(shù)組保存計(jì)算結(jié)果。這樣計(jì)算速度就會(huì)快很多缚柏。

class Solution {
    public int climbStairs(int n) {
        int[] steps=new int[n];
        if(n==1){
            return 1;
        }
        steps[0]=1;
        steps[1]=2;
        for(int i=2;i<n;i++){
            steps[i]=steps[i-1]+steps[i-2];
        }
        return steps[n-1];
    }
}

二苹熏、連續(xù)子數(shù)組的最大和

給定一個(gè)整數(shù)數(shù)組 nums ,找到一個(gè)具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個(gè)元素)币喧,返回其最大和柜裸。

示例 1:

輸入:nums = [-2,1,-3,4,-1,2,1,-5,4]
輸出:6
解釋:連續(xù)子數(shù)組 [4,-1,2,1] 的和最大,為 6 粱锐。

示例 2:

輸入:nums = [1]
輸出:1
示例 3:

輸入:nums = [0]
輸出:0

示例 4:

輸入:nums = [-1]
輸出:-1

示例 5:

輸入:nums = [-100000]
輸出:-100000

提示:

1 <= nums.length <= 3 * 104
-105 <= nums[i] <= 105

進(jìn)階: 如果你已經(jīng)實(shí)現(xiàn)復(fù)雜度為 O(n) 的解法疙挺,嘗試使用更為精妙的 分治法 求解。

解題思路

動(dòng)態(tài)規(guī)劃是本題的最優(yōu)解怜浅。動(dòng)態(tài)規(guī)劃的思路也很清晰铐然。假設(shè)有一個(gè)數(shù)組[-2,1],那么我們可以看到[-2,1]兩數(shù)的和比數(shù)組第二個(gè)元素1要小恶座。因此連續(xù)子數(shù)組的最大和為1搀暑。當(dāng)數(shù)組變?yōu)?code>[-2,1,-3]的時(shí)候,我們已經(jīng)知道[-2,1]這部分?jǐn)?shù)組的連續(xù)子數(shù)組的最大和為1跨琳。那么1跟[-3]比較是1比較大自点,因此這個(gè)數(shù)組的連續(xù)子數(shù)組的最大和依然為1。

簡而言之脉让,每次數(shù)組新增一個(gè)元素桂敛,都需要跟增加前的數(shù)組的連續(xù)子數(shù)組的最大和相比較,結(jié)果較大的那個(gè)就是新增后數(shù)組的連續(xù)子數(shù)組的最大和溅潜。代碼實(shí)現(xiàn)如下:

實(shí)現(xiàn)代碼

class Solution {
    public int maxSubArray(int[] nums) {
        int dp[]=new int[nums.length];
        dp[0]=nums[0];
        int max=dp[0];
        for(int i=1;i<dp.length;i++){
            //compare the num last status plus current num and current num 
            dp[i]=Math.max(dp[i-1]+nums[i],nums[i]);
            //compare max and dp[i],it will update max
            max=Math.max(max,dp[i]);
        }
        return max;
    }
}

三术唬、游戲幣組合

硬幣。給定數(shù)量不限的硬幣滚澜,幣值為25分粗仓、10分、5分和1分设捐,編寫代碼計(jì)算n分有幾種表示法借浊。(結(jié)果可能會(huì)很大,你需要將結(jié)果模上1000000007)

示例1:

輸入: n = 5
輸出:2
解釋: 有兩種方式可以湊成總金額:
5=5
5=1+1+1+1+1

示例2:

輸入: n = 10
輸出:4
解釋: 有四種方式可以湊成總金額:
10=10
10=5+5
10=5+1+1+1+1+1
10=1+1+1+1+1+1+1+1+1+1

說明:

注意:

你可以假設(shè):

0 <= n (總金額) <= 1000000

解題思路

這道題的狀態(tài)轉(zhuǎn)移方程似乎不那么容易看出來萝招,不過我們可以列一個(gè)表格來觀察一下蚂斤,看能不能發(fā)現(xiàn)一點(diǎn)什么規(guī)律。

硬幣數(shù)\總面值 1 2 3 4 5 6 7 8 9 10
1 1 0 0 0 1 0 0 0 0 1
2 0 1 0 0 0 1 0 0 0 1
3 0 0 1 0 0 0 1 0 0 0
4 0 0 0 1 0 0 0 1 0 0
5 0 0 0 0 1 0 0 0 1 0
6 0 0 0 0 0 1 0 0 0 1
7 0 0 0 0 0 0 1 0 0 0
8 0 0 0 0 0 0 0 1 0 0
9 0 0 0 0 0 0 0 0 1 0
10 0 0 0 0 0 0 0 0 0 1
f(n) 1 1 1 1 2 2 2 2 2 4

首先我們定義一個(gè)dp數(shù)組和所有的硬幣數(shù)組

 int[] dp = new int[n + 1];
 int[] coins = {1,5,10,25};

并且設(shè)置dp[0]=1,為邊界的條件即寒,作為完美能被一個(gè)硬幣表示的情況為 1橡淆。
dp[i]+=dp[i-coin]當(dāng)i-coin為0時(shí)結(jié)果為1,表示一個(gè)硬幣能表示的情況母赵。

我們可以簡單的得出狀態(tài)轉(zhuǎn)移方程

// 題目中需求對結(jié)果取模1000000007
dp[i] = dp[i] + dp[i - coin] 

代碼實(shí)現(xiàn)

class Solution {
    public int waysToChange(int n) {
       int dp[]=new int[n+1];
       int coins[]={1,5,10,25};
       dp[0]=1;

        for(int coin : coins) {
            for(int i = coin; i <= n; i++) {
                dp[i] = (dp[i] + dp[i - coin]) % 1000000007;
            }
        }
        return dp[n];
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逸爵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子凹嘲,更是在濱河造成了極大的恐慌师倔,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件周蹭,死亡現(xiàn)場離奇詭異趋艘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凶朗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門瓷胧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棚愤,你說我怎么就攤上這事搓萧。” “怎么了宛畦?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵瘸洛,是天一觀的道長。 經(jīng)常有香客問我次和,道長反肋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任踏施,我火速辦了婚禮石蔗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘畅形。我一直安慰自己抓督,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布束亏。 她就那樣靜靜地躺著铃在,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碍遍。 梳的紋絲不亂的頭發(fā)上定铜,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音怕敬,去河邊找鬼揣炕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛东跪,可吹牛的內(nèi)容都是我干的畸陡。 我是一名探鬼主播鹰溜,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼丁恭!你這毒婦竟也來了曹动?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤牲览,失蹤者是張志新(化名)和其女友劉穎墓陈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體第献,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贡必,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庸毫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仔拟。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖飒赃,靈堂內(nèi)的尸體忽然破棺而出理逊,到底是詐尸還是另有隱情,我是刑警寧澤盒揉,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布晋被,位于F島的核電站,受9級特大地震影響刚盈,放射性物質(zhì)發(fā)生泄漏羡洛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一藕漱、第九天 我趴在偏房一處隱蔽的房頂上張望欲侮。 院中可真熱鬧,春花似錦肋联、人聲如沸威蕉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽韧涨。三九已至,卻和暖如春侮繁,著一層夾襖步出監(jiān)牢的瞬間虑粥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工宪哩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留娩贷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓锁孟,卻偏偏與公主長得像彬祖,于是被迫代替她去往敵國和親茁瘦。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容