今天我們來一起研究一下比較奇怪的區間dp
先看一道例題
石子合併 很老的題了
1960: 石子合併
time limit: 1 sec memory limit: 128 mb
submit: 191 solved: 78
[submit][status][web board]
description
在乙個圓形操場的四周擺放著n 堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2 堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。
試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分和最大得分。
input
包含兩行,第1 行是正整數n(1<=n
<=100),表示有n堆石子。
第2行有n個數,分別表示每堆石子的個數。
output
輸出兩行。
第1 行中的數是最小得分;第2 行中的數是最大得分。
sample
input44
459sample
output
4354
01.暴力搜尋,我不相信你拿不到部分分......
02.暴力列舉 0102混合使用,效果更佳
03.區間dp
這是一種非常高效的做法我們不妨用dp[i][j]來表示從第i堆(包含i)到第j堆(包含j)石子的合併的最大代價
還要利用sum[i]做乙個字首和作為輔助
轉移方程為:dp[i][j]=maxmize * k從i到j(不包含j)*(最小的也一樣 自己yy)
len=2表示第一次合併的情況,此時合併的石子為2堆。此時,i從1到n-len+1,j=i+len-1
為了使我們進行的更為便捷,我們還需要進行乙個簡單的優化
即將複雜的環轉化簡單的鏈 這是一種十分有效的方法 用空間來換取操作上的簡便
為了方便大家的理解 我把自己的**給大家 並不好看……..
#include //看不慣的不要噴.....
using namespace std;
int a[205],f1[205][205],f2[205][205],sum[205];//最大 最小 字首和
inline int read()
while (ch >= '0' && ch <= '9')
return x * f;
}int main()
for(int i= n+1;i<= 2*n;i++)
for(int i = 1;i<= 2*n-1;i++)
for(int len = 3;len<= n;len++)}}
int minx = 0x3f3f3f,maxx = 0;
for(int i = 1;i<= n;i++)
printf("%d\n%d",minx,maxx);
return
0;}
POJ 3280 簡單區間 DP
就是想的時候不要想漏了轉移方式。對於乙個回文串 去掉最左和最右兩個後依然是回文串,好了。dp 轉移有三種,一種是從 dp i 1 j 轉移過來,一種是從 dp i j 1 轉移過來,一種是從 dp i 1 j 1 轉移過來 include include include include includ...
區間DP例題總結 看似不簡單的簡單題
今天,我們開始學那奇怪的區間dp。簡單來說,區間dp分為三個部分 階段列舉左端點,再列舉右端點 策略 顧名思義就是因為有些題,需要求出中點k,但有些題卻又不需要。所以我們應該判斷,用與不用。現在我們來看幾道經典例題 n堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成...
線性dp 區間dp
1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...