chenfy27的刷题记录

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

abc358E Alphabet Tiles

现有大写英文字母A-Z,个数分别为C[i],总共可以组成多少个长度在[1,K]之间的不同串?答案对998244353取模。
1<=K<=1000, 0<=C[i]<=1000

分析:记dp[i][k]表示前i类字母构成长度为k的不同方案数,枚举第i类字母的个数j进行转移。

#include <bits/stdc++.h>
using i64 = long long;
template<int MOD>
struct MInt {
i64 x;
int norm(i64 u) const {u%=MOD; if(u<0) u+=MOD; return u;}
MInt(i64 v=0):x(norm(v)) {}
int val() const {return x;}
MInt operator-() const {return MInt(norm(MOD-x));}
MInt inv() const {assert(x!=0); return power(MOD-2);}
MInt &operator*=(const MInt &o) {x=norm(x*o.x); return *this;}
MInt &operator+=(const MInt &o) {x=norm(x+o.x); return *this;}
MInt &operator-=(const MInt &o) {x=norm(x-o.x); return *this;}
MInt &operator/=(const MInt &o) {*this *= o.inv(); return *this;}
friend MInt operator*(const MInt &a, const MInt &b) {MInt ans=a; ans*=b; return ans;}
friend MInt operator+(const MInt &a, const MInt &b) {MInt ans=a; ans+=b; return ans;}
friend MInt operator-(const MInt &a, const MInt &b) {MInt ans=a; ans-=b; return ans;}
friend MInt operator/(const MInt &a, const MInt &b) {MInt ans=a; ans/=b; return ans;}
friend std::istream &operator>>(std::istream &is, MInt &a) {i64 u; is>>u; a=MInt(u); return is;}
friend std::ostream &operator<<(std::ostream &os, const MInt &a) {os<<a.val(); return os;}
MInt power(i64 b) const {i64 r=1, t=x; while(b){if(b&1) r=r*t%MOD; t=t*t%MOD; b/=2;} return MInt(r);}
};
using mint = MInt<998244353>;
std::vector<mint> fac, ifac;
struct Comb {
void init(int n) {
fac.assign(n + 1, 1);
for (int i = 1; i <= n; i++) {
fac[i] = fac[i - 1] * i;
}
ifac.resize(n + 1);
ifac[n] = fac[n].inv();
for (int i = n - 1; i >= 0; i--) {
ifac[i] = ifac[i + 1] * (i + 1);
}
}
int operator()(int n, int k) {
assert(n <= fac.size());
mint ans = fac[n] * ifac[k] * ifac[n - k];
return ans.val();
}
}comb;
void solve() {
int K;
std::cin >> K;
std::vector<int> C(27);
for (int i = 1; i <= 26; i++) {
std::cin >> C[i];
}
std::vector<std::vector<mint>> dp(27, std::vector<mint>(K + 1));
for (int i = 0; i <= 26; i++) {
dp[i][0] = 1;
}
for (int i = 1; i <= 26; i++) {
for (int k = 1; k <= K; k++) {
for (int j = 0; j <= std::min(C[i], k); j++) {
dp[i][k] += dp[i - 1][k - j] * comb(k, j);
}
}
}
mint ans = 0;
for (int k = 1; k <= K; k++) {
ans += dp[26][k];
}
std::cout << ans << "\n";
}
int main() {
std::cin.tie(0)->sync_with_stdio(0);
comb.init(1000);
int t = 1;
while (t--) solve();
return 0;
}

posted on   chenfy27  阅读(6)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示