Table of Contents

ExplanationImplementation

Official Analysis (C++)

Explanation

Let's consider our first round, where we have nn players and no damage has been dealt so far. Then, after this first round, any player with health in the range [1,n1][1, n-1] will be killed. In general, if we have ii heroes, and jj damage has been dealt so far, then any hero with health in the range [j+1,j+i1][j + 1, j + i - 1] will be killed in this round.

Notice that the ranges of health values that get killed in each around are disjoint. This indicates that we should do our counting based on the results from each round.

The only thing that affects which range of values gets killed in a round are the number of heroes ii that are alive, and the damage jj. Instead of thinking from the perspective of assigning health to the heroes currently alive, we instead assign health to the heroes that die, as the round that a hero dies in directly maps to a range of possible health values.

With this approach in mind, let's formulate a DP state dp[i][j]\texttt{dp}[i][j], which equals the number of ways we can assign health to the heroes that were killed, if ii of them are still alive and a total of jj damage has been dealt to all the heroes. Then, we have to consider three separate cases for the outcome of a round.

If no hero dies, we still need to consider this as a round that has been completed. Thus, we perform the following transition:

dp[i][j+i1]+=dp[i][j]\texttt{dp}[i][j + i - 1] \mathrel{+}= \texttt{dp}[i][j]

If some, but not all heroes die, then we know that the heroes who died had health values in the range [j+1,j+i1][j + 1, j + i - 1]. Also, we have to choose which heroes out of the ii heroes currently alive will die. Let kk be the new number of heroes after this round. Then, we have the following transition:

dp[k][j+i1]+=dp[i][j](iik)(min(xj,i1))ik\texttt{dp}[k][j + i - 1] \mathrel{+}= \texttt{dp}[i][j] \cdot {i \choose i - k} \cdot (\min(x - j, i - 1))^{i-k}

Lastly, if all the heros die, then we handle the transition in the exact same way as the previous one.

Implementation

Time Complexity: O(N2X)\mathcal{O}(N^2 X)

C++

#include <bits/stdc++.h>
using ll = long long;
Code Snippet: Binary Exponentiation (from the module) (Click to expand)
constexpr int MOD = 998244353;
int main() {
int n, x;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!