寫在前面
連個引言都不加就直接開
1. 區間dp狀態常見模板:
f[i][j]常常表示第i個到第j個這個區間內達到題目要求,所需要的最小值(最大值)
如:1. [石子合併](
這裡的f[i][j]表示將i~j堆石頭合併所需要的最小/大體力
1. [關路燈](
這裡的f[i][j][0/1]表示將i~j的區間的燈完全關閉,老人站在左/右端點時剩下的燈的總功率
1. [能量項鍊](
這裡的f[i][j]表示將i~j的珠子完全合併所能產生的最大能量
#### 總結:對於乙個區間dp的狀態設計來說,常常以f[i][j]進行第i個到第j個這個區間的狀態設計,並輔以第三維的變數來契合題目:
如[乘積最大](的一種狀態設計就是f[i][j][x]表示i~j的區間內使用x個乘號可以得到的最大值。
1. 區間dp狀態轉移方程模板:
f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+w(i,j));
如:1. [石子合併](
1 f[i][j]=max(f[i][k]+f[k+1][j]+w(i,j),f[i][j])23 =max(f[i][k]+f[k+1][j]+sum[j]-sum[i-1
],f[i][j])
45 又可以進一步優化得f[i][j]=max(f[i+1][j]]+sum[j]-sum[i-1],f[i][j-1]+sum[j]-sum[i-1]);
但其本質仍然是原模板
2.[又是關路燈](
1 f[i][j][0]=2 min(f[i+1][j][0]+(a[i+1]-a[i])*(sum[i] +sum[n]-sum[j]),f[i+1][j][1]+(a[j]-a[i])*(sum[i]+sum[n]-sum[j]));
34 f[i][j][1]=
5 min(f[i][j-1][0]+(a[j]-a[i])*(sum[i-1]+sum[n]-sum[j-1]),f[i][j-1][1]+(a[j]-a[j-1])*(sum[i-1]+sum[n]-sum[j-1]));這裡引用了[這篇z2415445508大佬的題解](原因是我懶得再推dp方程。~~
實質上,利用本題條件,如石子合併一樣將k優化為i+1或j-1同樣是是相同模板變形。
3.[能量項鍊我不想舉例子
](
f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+a[i+1]*a[k+1]*a[j]);
僅僅是w(i,j)稍有不同,這裡更可以看出原模板變形。
1. 邊界模板
邊界是我們區間dp時常常漏掉的一環,因為它實在是太顯而易見了( _~~然而並不是這樣~~_ )
以至於在我寫這裡的時候根本不知道該寫什麼
通常來說,區間dp的邊界是
(1<=i,j<=n;)
(i<=k<=j;)(=的新增與否由具體情況討論,我見過最多的是(i<=k懶的舉例子.
4.前言總結
所謂模板,只是用來在考試時幫助你認清題目本質的,一味套板是不可取的.
# 正文
1. 下定義!
"區間動態規劃是線性動歸的拓展,在劃分階段時,往往是以區間的長度從小到大為階段,逐步求解到到長度為n的區間的最優值,在列舉每乙個區間的最優值時,由於當前區間內又有很多種合併方式並到到當前區間,那麼就需要列舉這些合併方式中產生的值維護最優值,合併的不同,可以看作是區間劃分的不同,劃分時需要列舉劃分的位置,即分割點。 那麼對於區間類動態規劃問題,往往可以將問題分解成為兩兩合併的形式。其解決方法是對整個問題設最優解,列舉分割點,維護最優值。
————[一位巨佬](
這段話還是說得非常精彩的,揭露了區間dp的本質——小區間遞推大區間。
2.實現
```cpp
for(int l=1;l)
if(fu[k+1]==2
) }}
}
以上是[多邊形](我的部分**,其中:
1. l代表乙個區間的長度(這裡我定義的並非標準的長度,而是圖方便定義為(右端點-左端點)的值,標準的長度還要再加1;
2. i代表左端點的位置;
3. j代表左端點的位置;
4. k代表劃分的位置,即分割點。
問:為什麼要先列舉長度再列舉端點?
答:區間dp是由小區間遞推大區間的情況,若先端點再長度會出現大區間內有小區間的情況不明了的情況。
如:f[1][3]理應=f[1][2]+f[2][3]+w(1,3);但此時f[2][3]並未求出
3. 時間複雜度
樸素的區間dp的時間複雜度為o(n^3)
4. 破環成鏈
[双是石子合併](
**:
#includeusingnamespace
std;
int n,a[5000],sum[5000],f[5000][5000
],ans;
inline
void read(int &s)
while(ch>='
0'&&ch<='
9') s=s*10+ch-'
0',ch=getchar();
s=s*w;
return;}
intmain()
for(int i=n+1; i<=2*n; i++)
for(int l=1; l)
}for(int i=1; i<=n; i++)
printf(
"%d\n
",ans);
return0;
}
楊振寧也學會了瞎扯淡。
楊振寧也學會了瞎扯淡。看了廣為流傳的 楊振寧 中國不需諾獎 最缺蓋茨 的報道,咱不得不說,楊振寧也學會了扯淡,瞎說八道地誤導社會。一 楊振寧說 如果以平均素質來講,清華大學學生要比哈佛大學的要好。中國目前需要對大多數的平均學生的訓練,而美國需要十分傑出的年輕人創新來創造財富。美國式的教育哲學對有創造...
線性dp 區間dp
1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...
簡單的區間 dp
今天我們來一起研究一下比較奇怪的區間dp 先看一道例題 石子合併 很老的題了 1960 石子合併 time limit 1 sec memory limit 128 mb submit 191 solved 78 submit status web board description 在乙個圓形操場...