遞推(DP) noip 模擬 不等數列

2021-08-07 08:41:07 字數 1405 閱讀 9142

將 1到 n任意排列,然後在排列的每兩個數之間根據他們的大小關係插入「 >」

和「

第一行 2 個整數 n,k。
乙個整數表示答案。
5 2
66
對於 30%的資料: n <= 10

對於 100%的資料: k < n <= 1000

顯然這絕對不是一道暴力題。

很容易就能想到,從1到n將數字乙個個新增進去,同時每新增乙個數字,< 要麼多乙個,要麼不變。因此,我們用陣列f[i][j]表示前i個數字的所有排列中有j個《的排列個數。由於每新增乙個數字只能增加乙個《或者不增加,因此f[i][j]只能由f[i-1][j-1]和f[i-1][j]推出來。(f[i-1][j-1]考慮《增多的情況,f[i-1][j]考慮不變的情況)。

那麼怎樣新增可以使《增多呢?首先要明確一點:要新增進排列的數字一定比排列中所有的數字都大,因為我們是從1到n逐個新增的。然後,能夠新增的位置有四個:1.第乙個數字前,2.最後乙個數字後( < 會增多),3.新增在》關係的兩個數字間,3.新增在《關係的兩個數字間。

來看一下後兩種情況:

3.新增在》關係的兩個數字間:

很明顯,《符號多了乙個。

4.新增在《關係的兩個數字間:

很明顯,《數目不變。

同樣的,新增在最前面,《不變,新增在最後面會增多。

先看遞推式再解釋:f[i][j]=(f[i-1][j-1]*(i-j)%2012+f[i-1][j]*(j+1)%2012)%2012;

首先考慮f[i-1][j-1],很明顯,這要求將i新增後《多乙個,已知,每一種排列有j-1個

同樣的,對於f[i-1][j]我們考慮《不變的情況,即新增在《關係的兩個數字間或者最前面,易得為f[i-1][j]*(j+1)。

最後注意賦初值的問題。

#include

int f[1100][1100];

int n,k,i,j;

int min(int

x,int

y)int main()

for(i=1;i<=n;i++)

}printf("%d",f[n][k]);

}

班服 狀壓DP NOIP模擬賽

沒有題面。看到這個坑爹的資料量 最多10個班級 大概會對狀壓有一些想法 反正我是沒想到 本題暴搜可得50分 從資料量可以看出 狀態壓縮壓縮的是已選擇的班級而不可能是班服種類。dp i j 表示 前i種班服到達狀態j的方案數。首先,如果不選第i種班服,那麼dp i j dp i 1 j 如果要選第i種...

模擬 不高興的津津

津津上初中了。媽媽認為津津應該更加用功學習,所以津津除了上學之外,還要參加媽媽為她報名的各科複習班。另外每週媽媽還會送她去學習朗誦 舞蹈和鋼琴。但是津津如果一天上課超過八個小時就會不高興,而且,上得越久就會越不高興。假設津津不會因為其它事不高興,並且她的不高興不會持續到第二天。請你幫忙檢查一下津津下...

校內模擬 拯救(遞推)

這題年代可久遠了。似乎是今年寒假還是什麼時候loli的測試題來著?反正atp當時太水了不會做。現在越看越覺得當時很蛋疼 不過看這個題目的話,首先它的目標狀態是把所有的都變成0,所以會有乙個f i 表示把前i個都變成0所需要的最少步數 其次,它要改變第i個點的狀態一定是把前i 2個變成0並且把第i 1...