Working Optimization Algorithm
The simplest solution (in terms of saving you the time of understanding the literature) is probably going to be to use integer linear programming (ILP / MILP).  You can formulate it as an ILP instance, then apply an off-the-shelf ILP solver.

Introduce zero-or-one variables $x_{i,j}$, with the goal that $x_{i,j}=1$ means that the $i$th person is assigned to $j$th time slot, and $x_{i,j}=0$ means that they're not assigned to that time slot.  Now you can write down some linear inequalities/equations constraining these, e.g.,

$\sum_{i} x_{i,j} = n$ for each $i$ (each time slot needs to be filled with $n$ people)

$\sum_j x_{i,j} = c_i$ for each $i$, where $c_i = $ the number of shifts the $i$th worker should be assigned

Also if the $i$th worker isn't available for the $j$th slot, then add a constraint that $x_{i,j}=0$.

Also, $0 \le x_{i,j} \le 1$ (to force each $x_{i,j}$ to be zero or one).

The combination of all of these constraints gives you an integer linear program.  Ask the ILP solver to find a feasible solution, and boom, you're done.  This might not be the most efficient possible algorithm, but it will be simple to implement and play around with, and I expect that it'll give high-quality solutions and be fast enough for the size of problem you're likely to encounter in practice.