記一道有趣的筆試題,遞迴 動態規劃

2021-09-25 10:33:54 字數 1547 閱讀 4639

求:n個人排名,允許並列名次,共有多少種排名結果?

例如:a和b排名,有3種:

a>b

b>a

a=b和b=a算一種

我以前碰到過乙個類似的問題:

有個前提,忽略司機和乘務員。有n個人坐車,每輛車可以坐1~n個人,要求所有人都能上車,且所有車都必須上人,車足夠,問有多少種乘車方法?

這兩個問題真是如出一轍。

假設n個人,排出了m個名次,有f(n,m)種結果(1<=m<=n)

當m=1,f(n,m)=1;

當n綜合上述:

當m>n||m<1時,f(n,m)=0

當1==m時,f(n,m) = 1

當1所以,n個人的排名就是f(n,1)+f(n,2)+f(n,3)+…+f(n,n)

這裡重點理解一下當1#include

//n個人排m個名次

__int64 numofranknbym

(int n,

int m)

elseif(

1== m)

else

}//n個人排1~n個名次之和

__int64 sumnumofrank

(int n)

return sum;

}int

main()

}*/動態規劃就是遞推+備忘錄。

利用dp[i][j]表示有j個人,i種名次。那麼顯然有如下關係成立:

dp[i][i] = i! (i == j)

dp[1][j] = 1 (i == 1)

dp[i][j]=i*dp[i][j-1]+i*dp[i-1][j-1] (j > i > 1)

第一條是沒有並列的情況,直接全排列;

第二條是全部並列,顯然只有1種;

第三條是狀態轉移方程:當j-1個人排完名次之後加入乙個人,有兩種情況:

他和某乙個或幾個人並列,這種情況下之前就已經有i個排名了,他可能和這i種中的任何一種並列;

他有乙個新的名次,這種情況相當於他在i個空檔中選擇乙個,有i種可能。

而答案就是dp[i][j]對i求和。

#include

#define a 19

typedef

long

long ll;

ll dp[a]

[a];

//j個人排i個名次

ll ans[a]

;//j個人排名

ll fact[a]

;//階乘

//階乘

void

fac(

)//動態規劃求j個人排i個名次以及j個人排名

void

solve()

for(

int j =

1; j < a; j++

)for

(int i =

1; i <= j; i++

) ans[j]

+= dp[i]

[j];

}int

main()

就到這裡吧。

一道TCL的筆試題 遞迴

題目 在下面這個程式片段中的劃線處填上適當的表示式,使之逆序輸出陣列元素。void recur int a,int k 這道題目要用遞迴的思想完成陣列元素的逆序排列,我們先來複習一下有關遞迴函式一般解題思路。一般而言,遞迴函式要有乙個恰當的返回條件,以便到達那個條件的時候返回,不至於無窮巢狀進去,因...

一道筆試題

看到一道筆試題,跟自己想的有點出入,就跑了下,看了看原因。我稍微改了下 include int main int argc,char argv 輸出結果 c 5 d 245 press any key to continue vc6.0 debug下的彙編 5 unsigned char a 0xa...

一道筆試題

上次去筆試的時候,有一道題,怎麼也沒做出來,當時也是很緊張,有些思路,但卻沒有做出來。有四個人要過乙個獨木橋,因為天比較黑,而且橋只能允許兩個人同時通過,並且他們只有乙個手電筒。四個人單獨同時橋的時間是1,2,5,8分鐘。問最短的時間是多少?當時我的答案 1和8,1回來,1 5,1回來,1 2 8 ...