Here's the Gurobi code to solve the optimization problem:

```python
from gurobipy import Model, GRB

# Create a new model
model = Model("Work Optimization")

# Create variables
mary_hours = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Mary_Hours")
laura_hours = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Laura_Hours")
ringo_hours = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Ringo_Hours")
john_hours = model.addVar(lb=0, vtype=GRB.INTEGER, name="John_Hours")  # John's hours are integer

# Set objective function
model.setObjective(8.56 * mary_hours + 5.65 * laura_hours + 7.58 * ringo_hours + 7.27 * john_hours, GRB.MINIMIZE)

# Add constraints
model.addConstr(1.6 * laura_hours + 3.99 * john_hours >= 11, "c1")
model.addConstr(6.26 * mary_hours + 1.6 * laura_hours >= 31, "c2")
model.addConstr(1.6 * laura_hours + 5.57 * ringo_hours >= 26, "c3")
model.addConstr(5.57 * ringo_hours + 3.99 * john_hours >= 30, "c4")
model.addConstr(6.26 * mary_hours + 1.6 * laura_hours + 5.57 * ringo_hours + 3.99 * john_hours >= 30, "c5")
model.addConstr(0.76 * mary_hours + 4.04 * ringo_hours >= 51, "c6")
model.addConstr(4.04 * ringo_hours + 5.11 * john_hours >= 50, "c7")
model.addConstr(0.76 * mary_hours + 5.92 * laura_hours >= 26, "c8")
model.addConstr(5.92 * laura_hours + 4.04 * ringo_hours >= 36, "c9")
model.addConstr(0.76 * mary_hours + 5.92 * laura_hours + 4.04 * ringo_hours + 5.11 * john_hours >= 36, "c10")
model.addConstr(-5 * mary_hours + 5 * john_hours >= 0, "c11")
model.addConstr(1.6 * laura_hours + 3.99 * john_hours <= 50, "c12")
model.addConstr(6.26 * mary_hours + 5.57 * ringo_hours <= 95, "c13")
model.addConstr(1.6 * laura_hours + 5.57 * ringo_hours <= 79, "c14")
model.addConstr(6.26 * mary_hours + 5.57 * ringo_hours + 3.99 * john_hours <= 99, "c15")
model.addConstr(5.92 * laura_hours + 4.04 * ringo_hours <= 75, "c16")
model.addConstr(5.92 * laura_hours + 5.11 * john_hours <= 174, "c17")
model.addConstr(0.76 * mary_hours + 4.04 * ringo_hours <= 227, "c18")
model.addConstr(0.76 * mary_hours + 5.92 * laura_hours <= 188, "c19")
model.addConstr(4.04 * ringo_hours + 5.11 * john_hours <= 67, "c20")


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print('Obj: %g' % model.objVal)
    for v in model.getVars():
        print('%s %g' % (v.varName, v.x))
elif model.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {model.status}")
```
