一、講解
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...