進(jìn)一步理解動(dòng)態(tài)規(guī)劃

理解動(dòng)態(tài)規(guī)劃局骤、BFS和DFS一文中攀圈,只是初步講解了一下動(dòng)態(tài)規(guī)劃,理解的并不到位峦甩,這里再加深理解一下赘来。

本文主要參考什么是動(dòng)態(tài)規(guī)劃一文现喳。

一、前言

1.1犬辰、算法問(wèn)題的求解過(guò)程

類似于機(jī)器學(xué)習(xí)的步驟嗦篱,對(duì)同一個(gè)問(wèn)題,可以用不同的模型建模幌缝,然后對(duì)于確定的模型灸促,可以用不同的算法求解。

一般的算法問(wèn)題求解步驟涵卵,分為兩步:

  • 1浴栽、問(wèn)題建模:
    對(duì)于同一個(gè)問(wèn)題,可以有不同的模型轿偎。
  • 2典鸡、問(wèn)題求解:
    對(duì)于特定的模型,選出一個(gè)合適的算法(時(shí)間復(fù)雜度和空間復(fù)雜度滿足要求)坏晦,求解問(wèn)題萝玷。

對(duì)應(yīng)到動(dòng)態(tài)規(guī)劃算法上,具體分為這兩步:

  • 1英遭、問(wèn)題建模:[最優(yōu)子結(jié)構(gòu)]间护,[邊界][狀態(tài)轉(zhuǎn)移方程]挖诸。
  • 2汁尺、用動(dòng)態(tài)規(guī)劃算法求解問(wèn)題。

1.2多律、動(dòng)態(tài)規(guī)劃的思想

大事化小痴突,小事化了。把一個(gè)復(fù)雜的問(wèn)題分階段進(jìn)行簡(jiǎn)化狼荞,逐步化簡(jiǎn)成簡(jiǎn)單的問(wèn)題辽装。

1.3、動(dòng)態(tài)規(guī)劃的步驟

1.3.1 問(wèn)題建模
  • 1相味、 根據(jù)問(wèn)題拾积,找到【最優(yōu)子結(jié)構(gòu)】
    把原問(wèn)題從大化小的第一步丰涉,找到比當(dāng)前問(wèn)題要小一號(hào)的最好的結(jié)果拓巧,而一般情況下當(dāng)前問(wèn)題可以由最優(yōu)子結(jié)構(gòu)進(jìn)行表示。
  • 2一死、確定問(wèn)題的【邊界】肛度。
    根據(jù)上述的最優(yōu)子結(jié)構(gòu),一步一步從大化小投慈,最終可以得到最小的承耿,可以一眼看出答案的最優(yōu)子結(jié)構(gòu)冠骄,也就是邊界。
  • 3加袋、通過(guò)上述兩步凛辣,通過(guò)分析最優(yōu)子結(jié)構(gòu)與最終問(wèn)題之間的關(guān)系,我們可以得到【狀態(tài)轉(zhuǎn)移方程】锁荔。
1.3.2 問(wèn)題求解的各個(gè)方法(從暴力枚舉 逐步優(yōu)化到動(dòng)歸)
  • 暴力枚舉:
    下面的樓梯問(wèn)題蟀给,國(guó)王與金礦問(wèn)題蝙砌,還有最少找零硬幣數(shù)問(wèn)題阳堕,都可以通過(guò)多層嵌套循環(huán)遍歷所有的可能,將符合條件的個(gè)數(shù)統(tǒng)計(jì)起來(lái)择克。只是時(shí)間復(fù)雜度是指數(shù)級(jí)的恬总,所以一般 不推薦。

  • 遞歸:
    1肚邢、既然是從大到小壹堰,不斷調(diào)用狀態(tài)轉(zhuǎn)移方程,那么就可以用遞歸骡湖。
    2贱纠、遞歸的時(shí)間復(fù)雜度是由階梯數(shù)和最優(yōu)子結(jié)構(gòu)的個(gè)數(shù)決定的。不同的問(wèn)題响蕴,用遞歸的話可能效果會(huì)大不相同谆焊。
    3、在階梯問(wèn)題浦夷,最少找零問(wèn)題中辖试,遞歸的時(shí)間復(fù)雜度和空間復(fù)雜度都比動(dòng)歸方法的差, 但是在國(guó)王與金礦的問(wèn)題中劈狐,遞歸的時(shí)間復(fù)雜度和空間復(fù)雜度都比動(dòng)歸方法好罐孝。這是需要注意的。

每一種算法都沒(méi)有絕對(duì)的好與壞肥缔,關(guān)鍵看應(yīng)用場(chǎng)景莲兢。、

上面這句話說(shuō)的很好续膳,不止于遞歸和動(dòng)歸改艇,一般的算法也是,比如一般的排序算法姑宽,在不同的場(chǎng)景中遣耍,效果也大不相同。

  • 備忘錄算法:
    1炮车、在階梯數(shù)N比較多的時(shí)候舵变,遞歸算法的缺點(diǎn)就顯露出來(lái)了:時(shí)間復(fù)雜度很高酣溃。如果畫出遞歸圖(像二叉樹一樣),會(huì)發(fā)現(xiàn)有很多很多重復(fù)的節(jié)點(diǎn)纪隙。然而傳統(tǒng)的遞歸算法并不能識(shí)別節(jié)點(diǎn)是不是重復(fù)的赊豌,只要不到終止條件,它就會(huì)一直遞歸下去绵咱。
    2碘饼、為了避免上述情況,使遞歸算法能夠不重復(fù)遞歸悲伶,就把已經(jīng)得到的節(jié)點(diǎn)都存起來(lái)艾恼,下次再遇到的時(shí)候,直接用存起來(lái)的結(jié)果就行了麸锉。這就是備忘錄算法钠绍。
    3、備忘錄算法的時(shí)間復(fù)雜度和空間復(fù)雜度都得到了簡(jiǎn)化花沉。

  • 正經(jīng)的動(dòng)歸算法:
    1柳爽、上述的備忘錄算法,盡管已經(jīng)不錯(cuò)了碱屁,但是依然還是從最大的問(wèn)題磷脯,遍歷得到所有的最小子問(wèn)題,空間復(fù)雜度是O(N)娩脾。
    2赵誓、為了再次縮小空間復(fù)雜度,我們可以自底向上的構(gòu)造遞歸問(wèn)題晦雨,通過(guò)分析最優(yōu)子結(jié)構(gòu)與最終問(wèn)題之間的關(guān)系架曹,我們可以得到【狀態(tài)轉(zhuǎn)移方程】
    然后從最小的問(wèn)題不斷往上迭代闹瞧,即使一直到最大的原問(wèn)題绑雄,也是只依賴于前面的幾個(gè)最優(yōu)子結(jié)構(gòu)。這樣奥邮,空間復(fù)雜度就大大簡(jiǎn)化万牺。也就得到了正經(jīng)的動(dòng)歸算法。

下面通過(guò)幾個(gè)例題洽腺,來(lái)具體了解動(dòng)歸問(wèn)題脚粟。

二、例題

例1:Climbing Stairs

leetcode原題:你正在爬一個(gè)有n個(gè)臺(tái)階的樓梯蘸朋,每次只能上 1個(gè) 或者 2個(gè)臺(tái)階核无,那么到達(dá)頂端共有多少種不同的方法?

1.1藕坯、 建立模型

  • 最終問(wèn)題F(N):
    假設(shè)從0到達(dá)第N個(gè)臺(tái)階的方法共有F(N)個(gè)团南。
  • 最優(yōu)子結(jié)構(gòu)F(N-1)噪沙,F(xiàn)(N-2):
    到達(dá)N個(gè)臺(tái)階,有兩種可能吐根,第一種可能是從第 N-1 個(gè)臺(tái)階上1個(gè)臺(tái)階到達(dá)終點(diǎn)正歼,第二種可能是從第 N-2 個(gè)臺(tái)階上2個(gè)臺(tái)階到達(dá)終點(diǎn)。
  • 最優(yōu)子結(jié)構(gòu)與最終問(wèn)題之間的關(guān)系:
    按照上述表達(dá)拷橘,那么可以歸納出F(N) = F(N-1) + F(N-2) (n>=3)

結(jié)束條件為F(1) = 1,F(2) = 2

1.2局义、 問(wèn)題求解

1.2.1、 解法1:遞歸

先用比較容易理解的遞歸求解(結(jié)束條件已知冗疮,遞歸公式已知萄唇,可以直接寫代碼了)

class Solution:
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 1:
            return 1
        elif n == 2:
            return 2
        else:
            return self.climbStairs(n-1) + self.climbStairs(n-2)

回想前面所說(shuō),遞歸的時(shí)間復(fù)雜度是由階梯數(shù)和最優(yōu)子結(jié)構(gòu)的個(gè)數(shù)決定的赌厅。這里的階梯數(shù)是 N 穷绵,最優(yōu)子結(jié)構(gòu)個(gè)數(shù)是 2 。如果想象成一個(gè)二叉樹特愿,那么就可以認(rèn)為是一個(gè)高度為N-1,節(jié)點(diǎn)個(gè)數(shù)接近 2 的 N-1 次方的樹勾缭,因此此方法的時(shí)間復(fù)雜度可以近似的看作是O(2N) 揍障。

1.2.2、 解法2:備忘錄算法

參考什么是動(dòng)態(tài)規(guī)劃中遞歸的圖俩由,發(fā)現(xiàn)有很多相同的參數(shù)被重復(fù)計(jì)算毒嫡,重復(fù)的太多了。

所以這里我們想到了把重復(fù)的參數(shù)存儲(chǔ)起來(lái)幻梯,下次遞歸遇到時(shí)就直接返回該參數(shù)的結(jié)果兜畸,也就是備忘錄算法了,這里需要用到一個(gè)哈希表碘梢,解決方法就是對(duì)類用init進(jìn)行初始化咬摇。

class Solution:
    def __init__(self):
        self.map = {}
        
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        
        if n == 1:
            return 1
        if n == 2:
            return 2
        if n in self.map:
            return self.map[n]
        else:
            value  =  self.climbStairs(n-1) + self.climbStairs(n-2)
            self.map[n] = value
            return value

這里哈希表里存了 N-2 個(gè)結(jié)果,時(shí)間復(fù)雜度和空間復(fù)雜度都是O(N)煞躬。程序性能得到了明顯優(yōu)化肛鹏。

1.2.3、 解法3:動(dòng)態(tài)規(guī)劃

之前都是自頂向下的求解恩沛,考慮一下自底向上的求解過(guò)程在扰。從F(1)和F(2)邊界條件求,可知F(3) = F(1)+F(2)雷客。不斷向上芒珠,可知F(N)只依賴于前兩個(gè)狀態(tài)F(N-1)和F(N-2)。于是我們只需要保留前兩個(gè)狀態(tài)搅裙,就可以求得F(N)皱卓。相比于備忘錄算法总放,我們?cè)僖淮魏?jiǎn)化了空間復(fù)雜度。

這就是動(dòng)態(tài)規(guī)劃了好爬。(具體的細(xì)節(jié)看漫畫比較好理解局雄。)

具體代碼實(shí)現(xiàn)中,可以令F(N-2)=a存炮,F(xiàn)(N-1)=b炬搭,則temp等于a+b,然后把a(bǔ)向前挪一步等于b穆桂,b向前挪一步等于temp宫盔。那么下一次迭代時(shí),temp就依然等于a+b享完。

代碼如下:

class Solution:
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 1:
            return 1
        if n == 2:
            return 2
        a = 1
        b = 2
        for i in range(3,n+1):
            temp = a + b
            a = b
            b = temp
        return temp

例2: Making change using the fewest coins.

參考Dynamic Programming中灼芭,用最少的硬幣數(shù)目找零錢的一個(gè)例子。

問(wèn)題描述:
假設(shè)你是一家自動(dòng)售貨機(jī)制造商的程序員般又。你的公司正設(shè)法在每一筆交易 找零時(shí)都能提供最少數(shù)目的硬幣以便工作能更加簡(jiǎn)單彼绷。已知硬幣有四種(1美分,5美分茴迁,10美分寄悯,25美分)。假設(shè)一個(gè)顧客投了1美元來(lái)購(gòu)買37美分的物品 堕义,你用來(lái)找零的硬幣的最小數(shù)量是多少猜旬?
(這個(gè)問(wèn)題用貪心算法也能解,具體細(xì)節(jié)看參考文獻(xiàn))

2.1倦卖、 建立模型

就以動(dòng)歸作為解題的算法來(lái)建立模型吧洒擦。

  • 邊界:當(dāng)需要找零的面額正好等于上述的四種整額硬幣時(shí),返回1即可
  • 最優(yōu)子結(jié)構(gòu):回想找到最優(yōu)子結(jié)構(gòu)的方法怕膛,就是往后退一步熟嫩,能夠得到的最好的結(jié)果。這里有四個(gè)選擇嘉竟,1 + mincoins(63-1)邦危,1 + mincoins(63-5),1 + mincoins(63-10) 或者 1 + mincoins(63-25)舍扰,這四個(gè)選擇可以認(rèn)為是63的最優(yōu)子結(jié)構(gòu)倦蚪。
  • 狀態(tài)轉(zhuǎn)移方程:按照 上述的最優(yōu)子結(jié)構(gòu),mincoins(63)也就等于上述四個(gè)最優(yōu)子結(jié)構(gòu)的最小值边苹。于是陵且,方程可以表示為:

2.2、 問(wèn)題求解

模型已經(jīng)得到,接下來(lái)就運(yùn)用算法進(jìn)行求解慕购。
這里依然可以按照例1的解法聊疲,由模型,很自然的想到用遞歸求解沪悲。

2.2.1获洲、解法1,遞歸

邊界條件已知殿如,模型已知贡珊,可以直接寫代碼了。

def recMC(coinValueList,change):
    minCoins = change
    if change in coinValueList:
        return 1
    else:
        for i in [c for c in coinValueList if c <= change]:
            numCoins = 1 + recMC(coinValueList,change-i)
        if numCoins < minCoins:
            minCoins = numCoins
    return minCoins
print(recMC([1,5,10,25],63)

但是涉馁,對(duì)于每一個(gè)大于25的數(shù)目门岔,都有四個(gè)最優(yōu)子結(jié)構(gòu),然后對(duì)于每個(gè)最優(yōu)子結(jié)構(gòu)烤送,還有大量相同重復(fù)的參數(shù)(具體細(xì)節(jié)看參考)寒随。所以這個(gè)解法并不合適。

2.2.2帮坚、解法2妻往,動(dòng)態(tài)規(guī)劃

首先要有自底向上的思想,從change等于1時(shí)叶沛,開始往上迭代蒲讯,參考最優(yōu)子結(jié)構(gòu),記錄下來(lái)最少硬幣數(shù)灰署。一直迭代到63。

1==>1
2==>min(2-1) + 1 = 2
3==>min(3-1) + 1 = 3
4==>min(4-1) + 1 = 4
5==>min(min(5-1) + 1 = 5局嘁, min(5-5) + 1 = 1)= 1
6==>min(min(6-1) + 1 = 2溉箕, min(6-5) + 1 = 2)= 2
7==>min(min(7-1) + 1 = 3, min(7-5) + 1 = 3)= 3

由此可以推下去悦昵,每一個(gè)change對(duì)應(yīng)的最少硬幣數(shù)肴茄,都可以由前面的若干個(gè)最優(yōu)子結(jié)構(gòu)(有幾個(gè)最優(yōu)子結(jié)構(gòu),由change是多少?zèng)Q定但指,change大于5就有兩個(gè)子結(jié)構(gòu)寡痰,大于10就有三個(gè)。棋凳。)得到拦坠。這樣一直迭代到63,那么就可以得到63的最少硬幣數(shù)剩岳。

因此贞滨,需要一個(gè)循環(huán)來(lái)從頭到尾遍歷。
需要一定需要一個(gè)map來(lái)記錄部分結(jié)果拍棕。
每一個(gè)change晓铆,我們可以根據(jù)上面的式子遍歷最優(yōu)子結(jié)構(gòu)勺良,并將每個(gè)子結(jié)構(gòu)的結(jié)果都添加到一個(gè)list中,在遍歷完最有子結(jié)構(gòu)以后骄噪,選擇最小的那一個(gè)尚困,添加到map中去。

求解一個(gè)新的 i 的最優(yōu)解的過(guò)程是很方便的链蕊,從最優(yōu)子結(jié)構(gòu)中挑選最小的值然后加1即可事甜。
最優(yōu)子結(jié)構(gòu)的值,可以用minCoin[i-j]得到示弓。其中j為有效硬幣面額讳侨。

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

def dpMakeChange(coinValueList,change):
    minCoins = { }

    for cents in range(change+1):
        #cents小于等于1時(shí),coinCount會(huì)為空奏属,沒(méi)法執(zhí)行min跨跨。
        #因此這里先填上
        if cents <= 1:
            minCoins[cents] = cents
            continue
        #遍歷cents的每個(gè)最優(yōu)子結(jié)構(gòu)并且添加到list中,等待篩選
        coinCount = [ ]
        for j in coinValueList:
            if cents >= j:
                coinCount.append(minCoins[cents - j] + 1)
        minCoins[cents] = min(coinCount)
    return minCoins[change]

result = dpMakeChange([1,5,10,25],63)
print(result)

當(dāng)然這個(gè)函數(shù)是有瑕疵的囱皿,因?yàn)檫@個(gè)函數(shù)只告訴我們最少的硬幣數(shù)勇婴,并不能告訴我們應(yīng)該找零的面額。所以我們可以擴(kuò)展一下函數(shù)嘱腥,跟蹤記錄我們使用的硬幣即可耕渴。具體細(xì)節(jié)可以看參考。

例3: 國(guó)王與金礦問(wèn)題

只講一下大致的思路齿兔。
問(wèn)題中需要注意的地方:

  • 國(guó)王與金礦的問(wèn)題中橱脸,因?yàn)槊總€(gè)金礦需要的人不同,所含金礦數(shù)量也不同分苇。為了簡(jiǎn)化問(wèn)題添诉,這里第 i 個(gè)金礦所含的金礦數(shù)量和所需要的工人都是 特定不變的。
  • 在實(shí)現(xiàn)自底向上的遞推時(shí)医寿,因?yàn)閱?wèn)題的參數(shù)有兩個(gè)栏赴,那么存在兩個(gè)輸入維度。為此靖秩,可以畫一個(gè)表格來(lái)做分析须眷。
  • 在實(shí)現(xiàn)自底向上的遞推時(shí),為了比較快的找到規(guī)律沟突,最好把從邊界不斷地往上迭代花颗,結(jié)合最優(yōu)子結(jié)構(gòu)和存儲(chǔ)的結(jié)果,慢慢的找到規(guī)律事扭。

3.1捎稚、問(wèn)題建模

這里著重講解一下最后一點(diǎn),也就是動(dòng)態(tài)規(guī)劃最重要的地方妈经。

最優(yōu)子結(jié)構(gòu):對(duì)于5個(gè)金礦乔询,10個(gè)工人的情況耘沼,往后退一步存在兩種情況功戚。(第五個(gè)金礦的金礦數(shù)量為350丁存,所需工人為3人)

  • 情況1:國(guó)王選擇不挖第五個(gè)金礦蛾绎,那么此時(shí)最大化的金礦數(shù)量就是在有4個(gè)金礦群发,10個(gè)工人的情況下镊屎,能夠挖到的最多金礦數(shù)量宰睡。
  • 情況2:國(guó)王選擇挖第五個(gè)金礦蒲凶,那么此時(shí)用3個(gè)工人挖得350的金礦數(shù)量是已知的,還剩4個(gè)金礦與7個(gè)工人拆内。
    那么最優(yōu)解相當(dāng)于在4個(gè)金礦與7個(gè)工人的情況下能夠挖得的最多金礦數(shù)量 + 350旋圆。

最優(yōu)子結(jié)構(gòu)與最終問(wèn)題之間的關(guān)系:5個(gè)金礦10個(gè)工人的最優(yōu)選擇,就是上述兩個(gè)最優(yōu)子結(jié)構(gòu)的最大值麸恍。

于是我們可以得到狀態(tài)轉(zhuǎn)移方程:

最重要的狀態(tài)轉(zhuǎn)移方程已經(jīng)得到灵巧,至于剩下的邊界條件,現(xiàn)實(shí)中會(huì)遇到的各種特殊情況抹沪,這里就不贅述了刻肄。細(xì)節(jié)參考漫畫。

3.2融欧、問(wèn)題求解

3.2.1 解法1敏弃、遞歸

程序 :把狀態(tài)轉(zhuǎn)移方程翻譯成遞歸程序,遞歸的結(jié)束條件就是方程式中的邊界即可噪馏。
復(fù)雜度:因?yàn)槊總€(gè)狀態(tài)有兩個(gè)最優(yōu)子結(jié)構(gòu)麦到,所以遞歸的執(zhí)行流程類似于一個(gè)高度為N的二叉樹。所以方法的時(shí)間復(fù)雜度是O(2N)欠肾。

3.2.2 解法2隅要、備忘錄算法

程序:在簡(jiǎn)單遞歸的基礎(chǔ)上,增加一個(gè)HashMap備忘錄董济,用來(lái)存儲(chǔ)中間的結(jié)果,HashMap的Key是一個(gè)包含金礦數(shù)N和工人數(shù)W的對(duì)象要门,Value是最優(yōu)選擇獲得的黃金數(shù)虏肾。
復(fù)雜度:時(shí)間復(fù)雜度和空間復(fù)雜度相同,都等于被網(wǎng)絡(luò)中不同Key的數(shù)量欢搜。

3.2.3 解法3封豪、動(dòng)態(tài)規(guī)劃

為了實(shí)現(xiàn)自底向上的迭代,對(duì)于參數(shù)有兩個(gè)的問(wèn)題炒瘟,我們可以先畫要一個(gè)表格來(lái)做分析吹埠。根據(jù)狀態(tài)轉(zhuǎn)移方程,我們可以方便的畫出表格。注意缘琅,一定是要根據(jù)狀態(tài)轉(zhuǎn)移方程來(lái)求的粘都。

由于我們?cè)谇蠼饷總€(gè)格子的數(shù)值時(shí),結(jié)合狀態(tài)轉(zhuǎn)移方程刷袍,發(fā)現(xiàn)除了第一行以外翩隧,每一個(gè)格子都可以由前一行的格子中的一個(gè)或者兩個(gè)格子推導(dǎo)而來(lái)。
從整體上來(lái)說(shuō)呻纹,每一行的值都可以由前一行來(lái)求得堆生。

于是,我們?cè)趯懘a的時(shí)候雷酪,也可以像畫表格一樣淑仆,從左至右,從上到下一個(gè)一個(gè)的推出最終結(jié)果哥力。反映到程序上就是:

for i in range(金礦數(shù)):
    for j in range(工人數(shù)目):
         狀態(tài)轉(zhuǎn)移方程

另外蔗怠,由上可知,我們并不需要存儲(chǔ)整個(gè)表格省骂,只需要存儲(chǔ)前一行的結(jié)果即可推出新的一行蟀淮。

代碼這里就不寫了。

注意:

  • 這里動(dòng)態(tài)規(guī)劃的時(shí)間復(fù)雜度是O(n*w)钞澳,空間復(fù)雜度是O(w)怠惶。在n=5,w=1000是轧粟,顯然要計(jì)算5000次策治,開辟1000單位的空間。
  • 但是如果用簡(jiǎn)單遞歸算法的話兰吟,時(shí)間復(fù)雜度是O(2N)通惫,需要計(jì)算32次 ,開辟5單位(遞歸深度)的空間混蔼。
  • 這是由于動(dòng)態(tài)規(guī)劃方法的時(shí)間和空間都和w成正比履腋,而簡(jiǎn)單遞歸卻和w無(wú)關(guān),所以當(dāng)工人數(shù)量很多的時(shí)候惭嚣,動(dòng)態(tài)規(guī)劃反而不如遞歸遵湖。

所以說(shuō),每一種算法沒(méi)有絕對(duì)的好與壞晚吞,關(guān)鍵要看應(yīng)用場(chǎng)景延旧。

總結(jié):

個(gè)人覺(jué)得, 動(dòng)態(tài)規(guī)劃算法最重要的有兩點(diǎn)

  • 建模:一定要找對(duì)最優(yōu)子結(jié)構(gòu)槽地,然后分析最優(yōu)子結(jié)構(gòu)與最終問(wèn)題的關(guān)系迁沫,從而得到狀態(tài)轉(zhuǎn)移方程芦瘾。
  • 問(wèn)題求解:先手動(dòng)的自底向上的,運(yùn)用狀態(tài)轉(zhuǎn)移方程迭代一下集畅,一直到最終問(wèn)題近弟,從而確定程序的主體部分。

至于牡整,模型中的邊界問(wèn)題藐吮,特殊情況等,就是需要多敲代碼來(lái)慢慢考慮的了逃贝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谣辞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沐扳,更是在濱河造成了極大的恐慌泥从,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沪摄,死亡現(xiàn)場(chǎng)離奇詭異躯嫉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)杨拐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門祈餐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人哄陶,你說(shuō)我怎么就攤上這事帆阳。” “怎么了屋吨?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蜒谤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我至扰,道長(zhǎng)鳍徽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任敢课,我火速辦了婚禮阶祭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘直秆。我一直安慰自己胖翰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布切厘。 她就那樣靜靜地躺著,像睡著了一般懊缺。 火紅的嫁衣襯著肌膚如雪疫稿。 梳的紋絲不亂的頭發(fā)上培他,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音遗座,去河邊找鬼舀凛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛途蒋,可吹牛的內(nèi)容都是我干的猛遍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼号坡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼懊烤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起宽堆,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤腌紧,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后畜隶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壁肋,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年籽慢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浸遗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡箱亿,死狀恐怖跛锌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情极景,我是刑警寧澤察净,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站盼樟,受9級(jí)特大地震影響氢卡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜晨缴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一译秦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧击碗,春花似錦筑悴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至械拍,卻和暖如春突勇,著一層夾襖步出監(jiān)牢的瞬間装盯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工甲馋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留埂奈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓定躏,卻偏偏與公主長(zhǎng)得像账磺,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子痊远,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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