理解區間dp和例題

2021-10-09 22:30:00 字數 1292 閱讀 7175

一、講解

1、作用

用於不知道從**合併的動態規劃題,不比線性dp

2、解法步驟

即列舉區間長度,再列舉左端點,之後列舉區間的斷點進行轉移。

3、核心思路

既然讓我求解在乙個區間上的最優解,那麼我把這個區間分割成乙個個小區間,

求解每個小區間的最優解,再合併小區間得到大區間即可。所以在**實現上,

我可以列舉區間長度len為每次分割成的小區間長度(由短到長不斷合併),

內層列舉該長度下可以的起點,自然終點也就明了了。然後在這個起點終點之間列舉分割點,

求解這段小區間在某個分割點下的最優解。

4、**法

二、石子合併直線型

1、**

#include

#include

intmin

(int a,

int b)

intmain()

// 初始為0,dp[i][i]=0

memset

(dp,0,

sizeof

(dp));

// 列舉區間長度,從兩個區間開始

for(l=

2;l<=n;l++)}

}// for(i=1;i<=n;i++)

2、sum與dp陣列

sum是用來求兩個區間合併所需要花費的錢,而dp是乙個區間的已經花費的錢

參考資料:

區間dp入門

演算法學習之區間dp

三、能量項鍊環型

1、石子合併的sum是多變的,而這道題sum用head代替了,狀態轉移方程也變化了,主要看sum或者head,其他方面都沒改變

2、環變成直線的方法

本題由於是環,還需破環為列,可以開兩倍大的陣列,即a[i]=a[i+n],便可在第n顆珠子時求到第1顆珠子的頭標記(也即第n顆珠子的尾標記)

3、**

#include

#include

intmax

(int x,

int y)

intmain()

for(l=

2;l<=n;l++)}

}for

(i=1

;i<=n;i++

)printf

("%d"

,ans)

;}

參考資料

能量項鍊 (區間dp)

區間dp(模板 例題)

參考博文 區間dp小結 附經典例題 首先,什麼是區間dp?它是幹什麼的?先在小區間進行dp得到最優解,然後再利用小區間的最優解合併求大區間的最優解 操作往往涉及到區間合併問題 以上。模板如下 mst dp,0 初始化dp陣列 for int i 1 i n i for int len 2 len n...

區間dp暫時的理解

因為剛剛看了區間dp,所以寫一下對區間dp的理解。例題 51nod 1021 看了一篇部落格,覺得他說得比較容易理解,所以再次重複一遍 假如你是上帝,已經知道了1 n堆石子的最優解,那麼它肯定是由兩個子堆組成的,同理,兩個子堆也分別都有自己的兩個子堆,到最底層肯定是1 n堆石子的自身,那我們回到最初...

離散化例題 區間和

802.區間和 假定有乙個無限長的數軸,數軸上每個座標上的數都是0。現在,我們首先進行 n 次操作,每次操作將某一位置x上的數加c。接下來,進行 m 次詢問,每個詢問包含兩個整數l和r,你需要求出在區間 l,r 之間的所有數的和。輸入格式 第一行包含兩個整數n和m。接下來 n 行,每行包含兩個整數x...