鐵一中18年8 23模擬賽T1

2021-08-25 14:38:42 字數 1775 閱讀 6239

題意

給你1~n的排列,全部插入雙端佇列,最終佇列必須滿足1的左邊數列遞減,右邊遞增,即乙個v型,再以任意順序全部彈出。問第k個彈出的數為1的方案有多少種(mod 1e9+7),注意,兩個方案當且僅當它們某一次彈出的數不同時視為不同。

題解

首先我們要推出個有用的結論來轉化題意,在這裡,我們的重點是每次彈出的數。我們注意到每次能彈出的數為隊首或隊尾,要麼是左邊最大,要麼是右邊最大,顯然其中乙個必然是剩下全部數中最大的,不妨設是隊首。又因為以前左邊彈出的數都比隊首大,右邊彈出的數都比隊尾大,所以隊尾必然比所有以前彈出的所有數都小,所以隊尾必然比最小值小。整理一下,每次能彈出的數只有兩種可能

1. 沒彈的數中最大

2. 比已彈出的數中最小還要小用d

p[i]

[j] dp[

i][j

]表示已彈i個數,這i個數的最小值為j的方案數。

轉移時有兩種情況:一種是這次(第

i i

次)彈出j,那麼只要上一次時最小值大於j即可,同時這時j滿足條件2,所以可以彈出j;因為是排列,只有乙個j,所以這種情況下方案數為∑k

=j+1

ndp[

i−1]

[k]∗

1' role="presentation" style="position: relative;">∑nk

=j+1

dp[i

−1][

k]∗1

∑k=j

+1nd

p[i−

1][k

]∗1

另一種是以前最小為j,這次彈出數比j大,要轉移過來的狀態顯然為dp[i-1][j],但這時要滿足i+

j−1≤

n i+j

−1≤n

剩下的數中才有比j大的數,否則這種情況下方案數為0。在剩下的數中有比j大的數的情況下,條件2顯然不能滿足(要彈出的數比j大),對於dp[i-1][j]中每一種確定的方案,沒彈出的數字也確定了,因為是排列,沒彈的數中最大的數也只有對應的乙個,所以這種情況下方案數為dp

[i−1

][j]

∗1d p[

i−1]

[j]∗

1那麼最終方程為dp

[i][

j]=∑

nk=j

dp[i

−1][

k]d p[

i][j

]=∑k

=jnd

p[i−

1][k

],用s[i]陣列做字首和優化,時間複雜度為o(n2

n 2)

**

#include 

#include

using

namespace

std;

#define n 2005

const

int mod=1e9+7;

int n,k;

int dp[n][n],ss[n];

int mul(int a,int b)

return ret;

}int ksm(int a,int p)

return ret;

}int main()

printf("%d\n",mul(ksm(2,n-k-1),((dp[k][1]-dp[k-1][1])%mod+mod)%mod));

return

0;}

18年小結(一)

昨天過了33歲的生日。在 西遊記後傳 中,33年是乙個輪迴週期的數字,希望自己的人生也進入乙個新的階段吧。2018年已經過去了三分之二。我在這個2018所經歷的,幾乎是顛覆了自己這七八年來所建立的大部分認知和行事準則 最大程度的去接受變化和不確定性。要用乙個字總結現在的感受,就是 累 為什麼會累呢?...

實驗一中的OOP思想

子類繼承父類 父類中宣告了介面變數 介面ab中宣告了抽象方法 ab 在子類中 可以用這樣通俗的語句寫程式 while this.termination.shouldterminate pnew.g this.unary.mutate pnew.g,this.random pnew.x this.gp...

勞傷解(一) 中氣

原文 脾為己土,以太陰而主公升,胃為戊土,以陽明而主降。公升降之權,則在陰陽之交,是謂中氣。脾是已土,沿著太陰經而且主公升,胃是戊土,沿著陽明經而且主降,公升降的權利,則是在於陰陽的相交,這就是中氣。胃主受盛,脾主消磨,中氣旺則胃降而善納,脾公升而善磨,水谷腐熟,精氣滋生,所以無病。胃主要負責接受和...