楊老師的照相排列(線性dp)

2021-10-03 07:17:07 字數 1495 閱讀 1627

題意:

有n個人,身高分別是1,2,3,4…n,將這n個人排隊,要求從前(上面)往後(下面)身高增,從左往右身高也遞增。要求組成k排,每排需要的人數給出,問你有多少種排列的方法。

比如n=6,k=3,n1=3,n2=2,n3=1;那麼

123

456

就是一種合法排列。

資料範圍

1≤k≤5,學生總人數不超過30人。

思路:

按照要求,如果我們每次拿比上乙個大的,那麼必定可以形成合法排列,即我們從小到大去選人排列。然後在狀態轉移的時候,對於每乙個可以放的位置,那麼把這個人放進去之後,這個狀態的方案數=這個狀態的方案數+原來狀態的方案數。

那麼如何判斷乙個位置是否可以放人呢?

因為最多五層,且總人數不超過30人,那麼我們直接對每個狀態進行列舉,在當前狀態合法的情況下,判斷當前狀態可以由哪些狀態轉移過來,把合法的累加進去即可。

**

#include

using

namespace std;

typedef

long

long ll;

const

int n=

2e5+5;

const

int mod=

1e9+7;

const

int inf=

0x7fffffff

;const ll llinf=

0x7fffffffffffffff

;const

double eps=

1e-10

;#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

#define pb push_back

#define pii pair

#define fi first

#define se second

#define ls p<<1

#define rs p<<1|1

#define int long long

int dp[33]

[33][

33][33

][33]

;signed

main()

; dp[0]

[0][

0][0

][0]

=1;for

(int i=

1;i<=k;i++

)for

(int i=

0;i<=kk[1]

;i++)}

}}} cout<][kk[2]

][kk[3]

][kk[4]

][kk[5]

]<}}

楊老師的照相排列

dp的難點在於狀態的確定和轉移方程的推導.在本題中,我們可以從頭列舉,去觀察歸納,找到本題的最優子結構.假設有 k 1,a 3,2,1 對於第乙個數字1,它的數字一定是固定的 只能在最左上角 對於第二個數字,它可以位於1的右邊,也可以在1的下邊 通過列舉擺放的情況後,我們可以發現 第 i 行的擺放數...

題解 AcWing271 楊老師的照相排列

題面 經典的線性 text 設 dp 表示第 1 排有 a 個人,第 2 排有 b 個人,第 3 排有 c 個人,第 4 排有 d 個人,第 5 排有 e 個人的方案數。初始化 dp 1 可以發現乙個性質 前排的人數一定比後排的人數多。轉移可以參考 include define debug fpri...

C 勤奮的楊老師 dp應用 二分

時間限制 c c 1秒,其他語言2秒 空間限制 c c 32768k,其他語言65536k 64bit io format lld 楊老師認為他的學習能力曲線是乙個拱形。勤奮的他根據時間的先後順序羅列了乙個學習清單,共有n個知識點。但是清單中的知識並不是一定要學習的,可以在不改變先後順序的情況下有選...