解題記錄 排列小球

2022-06-05 06:54:07 字數 1604 閱讀 2016

題目描述:

給定三種型別的小球 p、q、r,每種小球的數量分別為 np、nq、nr 個。現在想將這些小球排成一條直線,但是不允許相同型別的小球相鄰,問有多少種排列方法。如若 np=2,nq=1,nr=1 則共有 6 種排列方式:pqrp,qprp,prqp,rpqp,prpq 以及 pqpr。如果無法組合出合適的結果,則輸出 0。

輸入描述:

一行以空格相隔的三個數,分別表示為 np,nq,nr。

輸出描述:

排列方法的數量。

輸入樣例:

2 1 1

輸出樣例:

6解題思路:

按排列中第乙個小球的型別不同(p、q或r),可將排列分為三類。總排列數為三類排列數的總和。設總的合法排列數為fall,第乙個球為p的合法排列數為fp(np, nq, nr),第乙個小球為q的合法排列數為fq(np, nq, nr),第乙個小球為r的合法排列數為fr(np, nq, nr)。則有:

fall = fp(np, nq, nr) + fq(np, nq, nr) + fr(np, nq, nr)

對於fp(np, nq, nr):

1. 若np <= 0,此時無法取出乙個p小球放到排列的第一位,因此第乙個球為p的合法排列數為0。

2. 若np == 1且nq == 0, nr == 0,此時取出乙個p小球放到排列第一位以後,所有的小球都已用盡且不會有相同的小球相臨。因此合法的排列數為1。

3. 若為其它情況,在取出乙個p小球放到排列第一位以後,剩餘的小球為:np - 1個p小球,nq個q小球,nr個r小球。要使排列合法,在對剩餘小球進行排列時,需要將q球或者r球放在第一位並保證後續排列合法,因此此時有:fp(np, nq, nr) = fq(np - 1, nq, nr) + fr(np - 1, nq, nr)。

對於fq(np, nq, nr)與fr(np, nq, nr)可做類似的分析。

至此,可通過將原來的問題一步步分解成規模更小的相同問題進行遞迴求解。通過乙個輔助的多維陣列記錄遞迴過程中產生的重複狀態來提高運算效率。**如下:

#include #include using namespace std;

int64_t fp(int np, int nq, int nr, vector> > >& rec);

int64_t fq(int np, int nq, int nr, vector> > >& rec);

int64_t fr(int np, int nq, int nr, vector> > >& rec);

int64_t fp(int np, int nq, int nr, vector> > >& rec)

return rec[0][np][nq][nr];

}int64_t fq(int np, int nq, int nr, vector> > >& rec)

return rec[1][np][nq][nr];

}int64_t fr(int np, int nq, int nr, vector> > >& rec)

return rec[2][np][nq][nr];

}int main()

總結:應該是個基礎的動態規劃題目吧,**寫得確實有點爛,不過懶得改了,就這樣,再接再勵吧。

Project Euler C C 解題記錄

這題沒什麼好說的。includeusing namespace std int main cout sum endl return 0 觀察可以發現,每隔2個斐波那契數就會有乙個偶數。a b b a 可以前進兩個數,且效率更高。includeusing namespace std int main ...

2020解題記錄

11.15 樹 二叉樹遍歷 flist fbi樹 猜數字cout min max 2 人以群分 最小環rem name batch for check rem author chen jie rem date 2020 10 17 rem description rename the bat fil...

python解題時間 Python解題記錄第9題

本文結構 題目資訊 位址 序號 描述 題目答案 簡要分析,程式 測試執行通過,含注釋 執行結果 霍霍磨刀 解答這道題目之前應掌握的知識基礎 解析過程 題目型別,分析以及實踐過程 斬獲成果 通過解答這道題目之後的知識提公升 做一件事,解一道題,其實就是逐步在規範自己 題目資訊 序號 9 描述 暫停一秒...