E - Alphabet Tiles
https://atcoder.jp/contests/abc358/tasks/abc358_e
思路
dp[i][j] --- 前i项组成j长度字符串的 方案总数。
状态转移为:
dp[i-1][j] * combination[j+l][l] ----> dp[i][j+l]
l == 0, 1, ..., ci
Code
https://atcoder.jp/contests/abc358/submissions/54674227
typedef long long ll; ll k; ll c[30]; const ll mode = 998244353; ll combination[1005][1005]; ll dp[30][1005]; void calc_combination(){ combination[0][0] = 1; for(int i=1; i<=1000; i++){ /* if none of i items is chosen, only one case exists */ combination[i][0] = 1; combination[i][i] = 1; for(int j=1; j<=i; j++){ /* if j item is chosen, the combination is from preceding i-1 items to chose j-1 items if j item is not chosen, all j items are from preceding i-i items. */ combination[i][j] = combination[i-1][j-1] % mode + combination[i-1][j] % mode; combination[i][j] %= mode; } } } int main() { calc_combination(); // cout << "----- after calc combination -------"<< endl; cin >> k; for(int i=1; i<=26; i++){ cin >> c[i]; } /* if target string length is zero, then the valid case number is one. */ dp[0][0] = 1; // cout << "----- dp init -------"<< endl; /* caculating dp */ for(int i=1; i<=26; i++){ for(int j=0; j<=k; j++){ for(int l=0; l<=c[i]; l++){ /* after adding i-th options, total length overflow k so to break */ if (j+l>k){ break; } /* otherwise, adding i-th item, the total case number can be calcuted based on the dp of the previous i-1 items. i.e. the previous i-1 items compromise j-l string length, l is the possible length to make string length less than k so for the left l chars, they can be filled by i-th item with the combination l of j. */ dp[i][j+l] += (dp[i-1][j] * combination[j+l][l]) % mode; dp[i][j+l] %= mode; } } } ll ans = 0; for(int i=1; i<=k; i++){ ans += dp[26][i]; ans %= mode; } cout << ans << endl; return 0; }
标签:Tiles,combination,int,Alphabet,ll,length,dp From: https://www.cnblogs.com/lightsong/p/18253455