CSES - Coding Company
Authors: Benjamin Qi, Andi Qu, Daniel Zhu
First, sort the people. This allows us to express the contribution of each team as . Let denote the skill of the -th person.
The number of ways we can form teams from the first people such that there are "unfinished" teams and the total penalty so far is . If the -th person is the least skilled in an unfinished team, we define its contribution to the penalty as . Similarly, finishing a team with person contributes to the penalty. These definitions follow directly from the previous observation that the contribution of a team is .
There are 4 cases when we transition from to :
- We make a team consisting of only person .
- transitions to the state (unfinished teams and penalty are not affected).
- We append person to an unfinished team.
- This transitions to the state (again, unfinished teams and penalty are not affected). There are unfinished teams we can choose to extend, so .
- We use person to "finish" an unfinished team.
- This transitions to the state (one less unfinished team, and we add to penalty as discussed above). There are again unfinished teams to choose from, so .
- We start a new unfinished team with person .
- This transitions to the state (one more unfinished team, and we subtract from penalty as discussed above).
Two more things:
- in our DP array can be negative, so just add 5000 to each ; there can be at most unfinished intervals, and each of them contributes at most .
- depends only on , so we can drop the first dimension that we store (to save memory).
I believe that this is called the "open and close interval trick". See zscoder's blog post for more information and problems.
#include <bits/stdc++.h>using namespace std;using ll = long long;const int M = 1e9 + 7;const int K = 5e3; // K is an offset to account for negativesint main() {int n;
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!