區(qū)間DP和回文為主題的DP

區(qū)間DP

區(qū)間DP的特征: 可以?xún)蓚€(gè)或多個(gè)部分進(jìn)行整合, 或者反過(guò)來(lái);能將問(wèn)題分解為能兩兩合并的形式.
區(qū)間DP的求解: 對(duì)整個(gè)問(wèn)題設(shè)最優(yōu)值屹篓,枚舉合并點(diǎn),將問(wèn)題分解為左右兩個(gè)部分界拦,最后合并兩個(gè)部分的最優(yōu)值得到原問(wèn)題的最優(yōu)值乍楚。

一般的方法是枚舉長(zhǎng)度(最外層L, 0 < L < N), 枚舉左端點(diǎn)(第二層i, 0 < i < N-L), 以此可確定右端點(diǎn)(j = i + L), 枚舉合并點(diǎn) (i <= t < j).
什么是枚舉合并點(diǎn)? 好比我要在一塊蛋糕的第i厘米到第j厘米直接切一刀, 可以切在哪里? 在i~j之間下的那一刀就是合并點(diǎn), 需要一個(gè)loop來(lái)枚舉.

ACwin石子合并

設(shè)有N堆石子排成一排,其編號(hào)為1丛楚,2族壳,3,…趣些,N仿荆。
每堆石子有一定的質(zhì)量,可以用一個(gè)整數(shù)來(lái)描述坏平,現(xiàn)在要將這N堆石子合并成為一堆拢操。
每次只能合并相鄰的兩堆,合并的代價(jià)為這兩堆石子的質(zhì)量之和功茴,合并后與這兩堆石子相鄰的石子將和新堆相鄰庐冯,合并時(shí)由于選擇的順序不同孽亲,合并的總代價(jià)也不相同坎穿。

例如有4堆石子分別為 1 3 5 2, 我們可以先合并1、2堆玲昧,代價(jià)為4栖茉,得到4 5 2, 又合并 1孵延,2堆吕漂,代價(jià)為9,得到9 2 尘应,再合并得到11惶凝,總代價(jià)為4+9+11=24;
如果第二步是先合并2犬钢,3堆苍鲜,則代價(jià)為7,得到4 7玷犹,最后一次合并代價(jià)為11混滔,總代價(jià)為4+7+11=22。

  • 思路
    經(jīng)典區(qū)間DP. 二維得相當(dāng)標(biāo)準(zhǔn).

這題會(huì)很容易記憶, 因?yàn)樽訂?wèn)題是"合并第i個(gè)物體到第j個(gè)物體的最優(yōu)解", 而原問(wèn)題則是 "已合并第1個(gè)物體到第N個(gè)物體的最優(yōu)解".

class Solution{
    public int mergeStones(int[] a){
        int[] arr = new int [a.length+1];
        int N = a.length;
        for(int i = 1;i <= N;i++){
            arr[i] += a[i-1];
        }
        for(int i = 1;i <= N;i++){
            arr[i] += arr[i-1];
        }
        
        //prefix sum
        int [][] dp = new int [N+1][N+1];
        for(int l = 2;l <= N;l++){ //枚舉區(qū)間長(zhǎng)度 - i到j(luò)之間的距離
            for(int i = 1;i + l <= N+ 1;i++){ //枚舉左端點(diǎn)
                int j = i + l -1;
                dp[i][j] = Integer.MAX_VALUE;
                for(int k = i;k<j;k++){ //k是合并點(diǎn), 此處枚舉合并點(diǎn), 從i到j(luò)之間都要考慮.
                    dp[i][j] = Math.min(dp[i][j], dp[i][k]+dp[k+1][j]+(arr[j] - arr[i-1]));
                }
            }
        }
        return dp[1][N];
    }
}

1000. Minimum Cost to Merge Stones

先枚舉區(qū)間長(zhǎng)度歹颓,再枚舉區(qū)間起始點(diǎn)坯屿,然后枚舉合并堆數(shù),再枚舉最后一個(gè)分割點(diǎn)巍扛。狀態(tài)轉(zhuǎn)移方程

class Solution:
    def mergeStones(self, stones: List[int], K: int) -> int:
        N = len(stones)
        if (N - 1) % (K - 1) != 0:
            return -1
        pre = [0 for _ in range(N+1)]
        pre[1] = stones[0]
        
        for i in range(2, N+1):
            pre[i] = pre[i-1] + stones[i-1]
        
        dp = [[0 for k in range(N)] for j in range(N)]
        for L in range(K, N+1):
            for i in range(0, N-L+1):
                j = i + L-1;
                dp[i][j] = float('inf')
                for mid in range(i, j, K-1):
                    dp[i][j] = min(dp[i][j], dp[i][mid] + dp[mid + 1][j])
                if (j - i) % (K - 1) == 0:
                    dp[i][j] += (pre[j+1] - pre[i]);
        
        return dp[0][N-1]

Burst balloon

Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and right are adjacent indices of i. After the burst, the left and right then becomes adjacent.
Find the maximum coins you can collect by bursting the balloons wisely.

Example:
Input: [3,1,5,8]
Output: 167
Explanation: nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167

    def maxCoins(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = [1]+nums+[1]
        N = len(nums)
        dp = [[0 for i in range(N)] for j in range(N)]
        for L in range(1, N):
            for i in range(0, N-L):
                j = i+L
                
                for k in range(i+1, j):
                    dp[i][j] = max(dp[i][j], nums[i] * nums[k] * nums[j]+dp[i][k]+dp[k][j])
        return dp[0][N-1]

回文相關(guān)的DP

  1. Palindrome Partitioning II
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末领跛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子撤奸,更是在濱河造成了極大的恐慌隔节,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寂呛,死亡現(xiàn)場(chǎng)離奇詭異怎诫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)贷痪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)幻妓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人劫拢,你說(shuō)我怎么就攤上這事肉津。” “怎么了舱沧?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵妹沙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我熟吏,道長(zhǎng)距糖,這世上最難降的妖魔是什么玄窝? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮悍引,結(jié)果婚禮上恩脂,老公的妹妹穿的比我還像新娘。我一直安慰自己趣斤,他們只是感情好俩块,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著浓领,像睡著了一般玉凯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上联贩,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天壮啊,我揣著相機(jī)與錄音,去河邊找鬼撑蒜。 笑死歹啼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的座菠。 我是一名探鬼主播狸眼,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浴滴!你這毒婦竟也來(lái)了拓萌?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤升略,失蹤者是張志新(化名)和其女友劉穎微王,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體品嚣,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炕倘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翰撑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罩旋。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖眶诈,靈堂內(nèi)的尸體忽然破棺而出涨醋,到底是詐尸還是另有隱情,我是刑警寧澤逝撬,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布浴骂,位于F島的核電站,受9級(jí)特大地震影響宪潮,放射性物質(zhì)發(fā)生泄漏溯警。R本人自食惡果不足惜趣苏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望愧膀。 院中可真熱鬧,春花似錦谣光、人聲如沸檩淋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蟀悦。三九已至,卻和暖如春氧敢,著一層夾襖步出監(jiān)牢的瞬間日戈,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工孙乖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浙炼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓唯袄,卻偏偏與公主長(zhǎng)得像弯屈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恋拷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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

  • 簡(jiǎn)介 區(qū)間dp资厉,顧名思義就是在一段區(qū)間上進(jìn)行動(dòng)態(tài)規(guī)劃。對(duì)于每段區(qū)間蔬顾,他們的最優(yōu)值都是由幾段更小區(qū)間的最優(yōu)值得到宴偿,是...
    Steven1997閱讀 6,530評(píng)論 0 2
  • 區(qū)間類(lèi)DP的做法,是用memorized search诀豁,把大區(qū)間拆分為小區(qū)間來(lái)解窄刘。而dp[i][j] 則直觀的表示...
    stepsma閱讀 599評(píng)論 0 1
  • 0x50「動(dòng)態(tài)規(guī)劃」例題 區(qū)間DP 線(xiàn)性DP從初態(tài)開(kāi)始,沿著“階段”向某個(gè)方向擴(kuò)張舷胜。而區(qū)間DP是線(xiàn)性DP的一種都哭,它...
    云中翻月閱讀 539評(píng)論 0 1
  • Description Given n balloons, indexed from 0 to n-1. Each...
    Nancyberry閱讀 277評(píng)論 0 0
  • 開(kāi)始刷leetcode,簡(jiǎn)單題就懶得寫(xiě)出來(lái)了逞带,把有點(diǎn)難度或者思路有趣的題記錄一下欺矫。寫(xiě)業(yè)務(wù)寫(xiě)久了,整個(gè)人都變蠢了展氓,需...
    bakaqian閱讀 1,463評(píng)論 2 1