玲瓏oj 1032A B(組合數學)

2021-07-22 18:01:40 字數 1673 閱讀 9206

1032 - a-b

time limit:1s

memory limit:128mbyte

submissions:528solved:105

description

你有n個球,需要把他們放到m個盒子裡。要求擁有最多球的盒子唯一,問方案數。

input

一行兩個數n、m(n、m≤500)

output

一行乙個數,表示方案數。答案對998244353取模。

sample input

5 2sample output

6思路:

測試資料很水,很暴力的dp也能過,o(n^3)

dp[i][j]表示i個盒子裡面一共放了j個球的情況。

假設球數最多的盒子裡面放了k個球,那麼剩下的m-1個盒子裡面只能放n-k個球,每個盒子最多[0,k-1]個球。

dp[i][j] = ∑dp[i-1][j-x], x∈[0, k]。

用pre[i][j]來求dp[i][j]的字首和來優化一下。

#include #include #include #include #include using namespace std;

#define ll long long

const ll mod = 998244353;

ll dp[550][550];

ll pre[550][550];

int main()*/

dp[i][j] = (pre[i-1][j] - (j-k>=0?pre[i-1][j-k]:0) + mod)%mod;

pre[i][j] = ((j==0?0:pre[i][j-1]) + dp[i][j])%mod;

}} ans = (ans+m*dp[m-1][n-k])%mod;

} printf("%lld\n", ans);

return 0;

}

看了玲瓏oj上面的題解,知道了一種

組合數學+容斥的解法

【ps:玲瓏oj上面的題解有點小錯誤,

利用容斥原理,最終的方案數=總方案數-不合法的方案數

find(i, j)表示將i個球放到j個盒子裡的方案數,盒子裡面允許為空

find(i, j) = c[i+j-1][j-1] 【這個公式不懂的可以參照這個部落格:codeforces397c】

先列舉第乙個盒子的數量,假設這是球數量最多的乙個盒子,記為x,然後列舉有k個盒子球的數量》=第乙個盒子

因此 ans = m*( find(n, m) - ∑((-1)^k) * (c[m-1][k] * find(n-x*(k+1),m-1) ) ), x∈[0,n], k∈[1,m-1]

#include #include #include #include #include using namespace std;

#define ll long long

const ll mod = 998244353;

ll c[1050][1050];

ll find(int x, int y)

int main()

ll ans = 0;

for(int x=0; x<=n; x++){

for(int k=1; k

計算組合數 oj

time limit 1000 ms memory limit 32768 kib submit statistic problem description 計算組合數。c n,m 表示從n個數中選擇m個的組合數。計算公式如下 若 m 0,c n,m 1 否則,若 n 1,c n,m 1 否則,若m...

組合數 南陽oj32 DFS

描述 找出從自然數1 2 n 0 輸入 輸入n r。輸出按特定順序輸出所有組合。特定順序 每乙個組合中的值從大到小排列,組合之間按逆字典序排列。樣例輸入 5 3 樣例輸出 543 542541 532531 521432 431421 321 include includeint m,n int v...

OJ求組合數 簡單的事情

oj簡單的事情 求組合數 問題描述 數學天才fans曾經說過一句話 組合數的計算是一件非常簡單的事情。組合數的計算真的是一件非常簡單的事情嗎?請你自己去嘗試一下吧!輸入輸入中的一些整數對n,m m n 20 輸出輸出其組合數。求組合數 組合數的計算雖說簡單但也不乏有些陷阱,這主要是因為語言中的資料型...