POJ2279 五維線性dp

2021-09-27 07:35:01 字數 3637 閱讀 9195

題面

poj2279題面

思路

從頭開始系統的學dp,做題目一定要理清dp的五大因素

狀態表示

用dp[a1,

a2,a

3,a4

,a

5a_1,a_2,a_3,a_4,a_5

a1​,a2

​,a3

​,a4

​,a5

​]表示第i行上已經插入了a

ia_i

ai​個人的排隊方法數

階段劃分

已經在各排分配了制定人數的方法數(對應乙個五元組)

轉移方程

寫不下了^ _ ^下面單列

邊界dp[0,0,0,0,0]=1,其餘均為0

目標dp[k1,

k2,k

3,k4

,k

5k_1,k_2,k_3,k_4,k_5

k1​,k2

​,k3

​,k4

​,k5

​]轉移方程及其理解:

d p[

a1,a

2,a3

,a4,

a5]=

dp[a_1,a_2,a_3,a_4,a_5]+dp[a_1-1,a_2,a_3,a_4,a_5] (a_1\geq 1 \space and \space a_1\leq k_1)\\ dp[a_1,a_2,a_3,a_4,a_5]+dp[a_1,a_2-1,a_3,a_4,a_5] (1 \leq a_2\leq a_1 \space and \space a_2\leq k_2)\\ \vdots \\ dp[a_1,a_2,a_3,a_4,a_5]+dp[a_1,a_2,a_3,a_4,a_5-1] (1 \leq a_5\leq a_4 \space and \space a_5\leq k_5) \end

dp[a1​

,a2​

,a3​

,a4​

,a5​

]=⎩⎪

⎪⎪⎪⎨

⎪⎪⎪⎪

⎧​dp

[a1​

,a2​

,a3​

,a4​

,a5​

]+dp

[a1​

−1,a

2​,a

3​,a

4​,a

5​](

a1​≥

1and

a1​≤

k1​)

dp[a

1​,a

2​,a

3​,a

4​,a

5​]+

dp[a

1​,a

2​−1

,a3​

,a4​

,a5​

](1≤

a2​≤

a1​a

nda2

​≤k2

​)⋮d

p[a1

​,a2

​,a3

​,a4

​,a5

​]+d

p[a1

​,a2

​,a3

​,a4

​,a5

​−1]

(1≤a

5​≤a

4​an

da5​

≤k5​

)​其實狀態的尋找是不好做的,對於最終目標,如何找出表示目標的維度,如何分解問題,使其在求解每個子問題的"階段"都具有"子問題重疊性",「無後效性"和"最優子結構性質」。

性質解釋

子問題重疊性

問題可劃分成多個子問題,並且子問題具有相似性,可以歸納

無後效性

已經求解的子問題不受後續階段的影響

最優子結構性質

下一階段的最優解能夠由前面各階段的子問題的最優解匯出

這三個性質是判斷尋找的狀態是否具有動態規劃條件的性質。

能想到的是,對於乙個人的狀態肯定可以計算,用乙個人算兩個人的狀態也可以算,而後面的狀態加乙個人好像也可以算,仔細想一下,如果自己打個表的話,可以從1開始人數乙個乙個向上推(其實就是動態規劃的模擬),想到這種模擬,基本上三個性質都具備了(請讀者自行思考),如果想到人數為維度的話,為了能夠表示每一排的情況,容易想到用五元組表示狀態的方法。

對於初態,如果五個空都沒有乙個人的話,肯定預設只有一種排法,所以dp[0,0,0,0,0]=1,對於剛剛所謂的乙個人乙個人地向上推,其實就是對於當前狀態對於五元組每乙個元討論少乙個人的情況,假設我們插人是從低到高插入的,那個人排在哪一排反正是從低到高排肯定在是固定的在排首的,其實就是其他人的站位影響了照相順序,也就是加上其他人站位的方法數即可(就是+dp

[a1,

a2−1

,a3,

a4,a

5]

+dp[a_1,a_2-1,a_3,a_4,a_5]

+dp[a1

​,a2

​−1,

a3​,

a4​,

a5​]

這類的原因 ),但是這保證了每一排是從低到高,但要保證每一列從低到高,那就要當第i-1排比i排少人的時候,就不能排在第i排,因為下面總有乙個更高的要插在i-1排,就不是從低到高了,同時還要滿足插人不多於給出的限制,那就是(1≤

ai≤a

i−1a

ndai

≤ki)

(1 \leq a_i\leq a_i-1 \space and \space a_i\leq k_i)

(1≤ai​

≤ai​

−1an

dai​

≤ki​

)了唄注意事項

1)dp一般0陣列的0軸是初態,所以一般迴圈要<=限制,答案訪問上界而不是上界-1

2)要注意陣列(無向圖)的遍歷的範圍,不要少了也不要越界

3)函式內部按大小直接宣告dp陣列,否則會mle(c++14以上的編譯器陣列可以直接用變數宣告)

**

//這個是按照上面的轉移方程寫的,是在此狀態訪問上一次狀態的情況

#include #include using namespace std;

typedef long long ll;

const int maxn = 31;

int nk[6];

int main()

ll dp[nk[0]+1][nk[1]+1][nk[2]+1][nk[3]+1][nk[4]+1];

memset(dp,0,sizeof(dp));

dp[0][0][0][0][0] = 1;

for(int i = 0;i <= nk[0];i++)}}

}}

cout << dp[nk[0]][nk[1]][nk[2]][nk[3]][nk[4]]=1了,

//需要在i ==k[1]的時候阻止其進一步向下求,也就是要有(i < n[1])的判斷

#include #include #include typedef long long ll;

using namespace std;

int n[6], k;

void work()

cout << f[n[1]][n[2]][n[3]][n[4]][n[5]] << endl;

}int main()

POJ 1187 隕石的秘密 (線性DP)

題意 公元11380年,一顆巨大的隕石墜落在南極。於是,災難降臨了,地球上出現了一系列反常的現象。當人們焦急萬分的時候,一支中國科學家組成的南極考察隊趕到了出事地點。經過一番偵察,科學家們發現隕石上刻有若干行密文,每一行都包含5個整數 1 1 1 1 6 0 0 6 3 57 8 0 11 3 28...

POJ 2948 經典二維dp

一開始不知道怎麼解決後效性,以為自己記錄狀態的方式錯了,實際上是轉移方程想錯了 學習了 如果怎麼dp都發覺有後效性,一定是dp的姿勢不對 dp i j 如果採用向左的決策,要從dp i 1 j 轉移過來,如果採用向上的決策,要從dp i j 1 轉移過來,這樣前面的方程裡怎麼決策才不會對後來那個方程...

相似基因,二維的線性dp

時間限制 1.0s 空間限制 2.5mb 大家都知道,基因可以看作乙個鹼基對序列。它包含了4種核苷酸,簡記作a,c,g,t。生物學家正致力於尋找人類基因的功能,以利用於診斷疾病和發明藥物。在乙個人類基因工作組的任務中,生物學家研究的是 兩個基因的相似程度。因為這個研究對疾病的 有著非同尋常的作用。兩...