求: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 ...