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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】