Wannafly 挑戰賽16 A 取石子
阿新 • • 發佈:2018-05-27
def 表示 ++i 備註 spl one str 打表 sub 題目描述
給出四堆石子,石子數分別為a,b,c,d。規定每次只能從堆頂取走石子,問取走所有石子的方案數。
輸入描述:
在一行內讀入四個由空格分隔的整數a,b,c,d, 輸入均為不超過500的正整數
輸出描述:
輸出一個整數表示答案,答案對109+7取模示例1 輸入
3 5 4 2輸出
2522520
備註:
輸入均為不超過500的正整數
【分析】
每一堆的石子之間的相對位置是固定不變的,所以可以通過插入來生成一個取石子的順序,而插入的求解則可以利用組合數來計算。 起始的時候,把第一堆的$$$a$$$個石頭擺好,相當於在$$$a$$$個空位放下$$$a$$$個石頭,由於石頭順序是固定的,所以有$$$C^a_a$$$種,也就是1種;
接下來,把第二堆的$$$b$$$個石頭也加進來,要在$$$a$$$個石頭之間以及兩邊插入$$$b$$$個石頭,等價於一共有$$$a+b$$$個位置,在其中選$$$b$$$個位置,作為放置$$$b$$$的地方,由於$$$b$$$的順序確定,所以組合數為$$$C^b_{a+b}$$$個
然後把第三堆的$$$c$$$個石頭也加進來,在$$$a+b$$$個石頭插入$$$c$$$個石頭,同理,組合數為$$$C^c_{a+b+c}$$$個;
第四堆的$$$d$$$加進來就是$$$C^d_{a+b+c+d}$$$個。 所以最終答案為$$$C^a_a \times C^b_{a+b} \times C^c_{a+b+c} \times C^d_{a+b+c+d}$$$個
【註意】
組合數較大需要用long long存放;對答案需要取模 可以對組合數打表,來避免分數取模,公式為$$$C^x_y = C^x_{y-1} + C^{x-1}_{y-1}$$$
【代碼】
#include<stdio.h> #define N_max 2005 int n; typedef long long ll; #define mod 1000000007 ll C[N_max][N_max] = { 0 }; int main() { int a[4]; ll res = 1; for (int t = 0; t < N_max; ++t)C[t][0]=1; for (int i = 1; i <N_max; ++i) for (int j = 1; j <=i; ++j) { C[i][j] = (C[i - 1][j - 1] + C[i - 1][j])%mod; } for (int i = 0; i < 4; ++i) { scanf("%d", a + i); } res = C[a[0]][a[0]]; res = res*C[a[0] + a[1]][a[1]]%mod; res = res*C[a[0] + a[1]+a[2]][a[2]]%mod; res = res*C[a[0] + a[1]+a[2]+a[3]][a[3]]%mod; printf("%lld", res); return 0; }
Wannafly 挑戰賽16 A 取石子