【SSLOJ1519】揹包簽到題
阿新 • • 發佈:2020-09-13
題目
思路
顯然每一個物品是獨立的,所以將每一個物品的方案數分別求出來,然後相乘即可。
因為 \(a\leq 100\),所以我們可以列舉最終選擇了多少個該物品。假設選擇了 \(j\) 個該物品,一共要進行 \(m\) 輪遊戲,插板法可以得出
\[ans=\sum^{a_i}_{j=0} \binom{j+m-1}{j} \]
發現這個組合數中 \(j\) 只有 \(100\),所以可以遞推求出。
時間複雜度 \(O(nm\log \operatorname{MOD}+\max(a)·m)\)。
程式碼
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=110,MOD=998244353; ll n,m,p,ans,sum,C[N][N]; ll fpow(ll x,ll k) { ll ans=1; for (;k;k>>=1,x=x*x%MOD) if (k&1) ans=ans*x%MOD; return ans; } int main() { scanf("%lld%lld",&n,&m); ans=1; for (ll i=0;i<=100;i++) { C[i][0]=1; for (ll j=1;j<=min(i+m-1,-1LL+N);j++) C[i][j]=C[i][j-1]*fpow(j,MOD-2)%MOD*((i+m-1-(j-1))%MOD)%MOD; } while (n--) { scanf("%lld",&p); sum=0; for (int i=0;i<=p;i++) sum=(sum+C[i][i])%MOD; ans=ans*sum%MOD; } cout<<ans; return 0; }