```json
{
  "sym_variables": [
    ("x0", "hours worked by George"),
    ("x1", "hours worked by Jean"),
    ("x2", "hours worked by Dale"),
    ("x3", "hours worked by Ringo"),
    ("x4", "hours worked by Bill")
  ],
  "objective_function": "1*x0 + 4*x1 + 2*x2 + 4*x3 + 8*x4",
  "constraints": [
    "3.93*x3 + 2.49*x4 >= 18",
    "4.64*x2 + 2.49*x4 >= 41",
    "1.38*x1 + 3.93*x3 + 2.49*x4 >= 47",
    "1.38*x1 + 4.64*x2 + 2.49*x4 >= 47",
    "1.38*x1 + 3.93*x3 + 2.49*x4 >= 43",
    "1.38*x1 + 4.64*x2 + 2.49*x4 >= 43",
    "3.74*x1 + 1.07*x4 >= 12",
    "5.04*x0 + 3.74*x1 >= 15",
    "3.74*x1 + 5.86*x3 >= 14",
    "0.56*x2 + 1.07*x4 >= 14",
    "5.04*x0 + 0.56*x2 >= 10",
    "5.04*x0 + 0.56*x2 + 1.07*x4 >= 16",
    "3.93*x3 + 2.49*x4 <= 129",
    "1.29*x0 + 1.38*x1 <= 207",
    "4.64*x2 + 3.93*x3 <= 214",
    "1.29*x0 + 1.38*x1 + 4.64*x2 + 3.93*x3 + 2.49*x4 <= 214",
    "5.04*x0 + 3.74*x1 <= 94",
    "3.74*x1 + 1.07*x4 <= 149",
    "5.04*x0 + 1.07*x4 <= 86",
    "3.74*x1 + 0.56*x2 <= 124",
    "5.04*x0 + 5.86*x3 <= 82",
    "5.86*x3 + 1.07*x4 <= 84",
    "0.56*x2 + 1.07*x4 <= 87",
    "5.04*x0 + 3.74*x1 + 0.56*x2 + 5.86*x3 + 1.07*x4 <= 87",
    "5.22*x0 + 4.63*x4 <= 27",
    "1.67*x1 + 2.74*x3 <= 79",
    "1.67*x1 + 3.29*x2 + 4.63*x4 <= 85",
    "1.67*x1 + 3.29*x2 + 2.74*x3 <= 45",
    "5.22*x0 + 1.67*x1 + 3.29*x2 <= 51",
    "5.22*x0 + 2.74*x3 + 4.63*x4 <= 66",
    "5.22*x0 + 3.29*x2 + 4.63*x4 <= 54",
    "1.67*x1 + 2.74*x3 + 4.63*x4 <= 67",
    "5.22*x0 + 1.67*x1 + 2.74*x3 <= 81",
    "3.29*x2 + 2.74*x3 + 4.63*x4 <= 42",
    "5.22*x0 + 1.67*x1 + 3.29*x2 + 2.74*x3 + 4.63*x4 <= 42",
    "x0 >= 0",
    "x1 >= 0",
    "x2 >= 0",
    "x3 >= 0",
    "x4 >= 0"
  ]
}
```

```python
import gurobipy as gp

# Create a new model
m = gp.Model("optimization_problem")

# Create variables
x = m.addVars(5, lb=0, vtype=gp.GRB.CONTINUOUS, names=["George", "Jean", "Dale", "Ringo", "Bill"])

# Set objective function
m.setObjective(1*x[0] + 4*x[1] + 2*x[2] + 4*x[3] + 8*x[4], gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(3.93*x[3] + 2.49*x[4] >= 18)
m.addConstr(4.64*x[2] + 2.49*x[4] >= 41)
m.addConstr(1.38*x[1] + 3.93*x[3] + 2.49*x[4] >= 47)
m.addConstr(1.38*x[1] + 4.64*x[2] + 2.49*x[4] >= 47)
m.addConstr(1.38*x[1] + 3.93*x[3] + 2.49*x[4] >= 43)
m.addConstr(1.38*x[1] + 4.64*x[2] + 2.49*x[4] >= 43)
m.addConstr(3.74*x[1] + 1.07*x[4] >= 12)
m.addConstr(5.04*x[0] + 3.74*x[1] >= 15)
m.addConstr(3.74*x[1] + 5.86*x[3] >= 14)
m.addConstr(0.56*x[2] + 1.07*x[4] >= 14)
m.addConstr(5.04*x[0] + 0.56*x[2] >= 10)
m.addConstr(5.04*x[0] + 0.56*x[2] + 1.07*x[4] >= 16)
m.addConstr(3.93*x[3] + 2.49*x[4] <= 129)
m.addConstr(1.29*x[0] + 1.38*x[1] <= 207)
m.addConstr(4.64*x[2] + 3.93*x[3] <= 214)
m.addConstr(1.29*x[0] + 1.38*x[1] + 4.64*x[2] + 3.93*x[3] + 2.49*x[4] <= 214)
m.addConstr(5.04*x[0] + 3.74*x[1] <= 94)
m.addConstr(3.74*x[1] + 1.07*x[4] <= 149)
m.addConstr(5.04*x[0] + 1.07*x[4] <= 86)
m.addConstr(3.74*x[1] + 0.56*x[2] <= 124)
m.addConstr(5.04*x[0] + 5.86*x[3] <= 82)
m.addConstr(5.86*x[3] + 1.07*x[4] <= 84)
m.addConstr(0.56*x[2] + 1.07*x[4] <= 87)
m.addConstr(5.04*x[0] + 3.74*x[1] + 0.56*x[2] + 5.86*x[3] + 1.07*x[4] <= 87)
m.addConstr(5.22*x[0] + 4.63*x[4] <= 27)
m.addConstr(1.67*x[1] + 2.74*x[3] <= 79)
m.addConstr(1.67*x[1] + 3.29*x[2] + 4.63*x[4] <= 85)
m.addConstr(1.67*x[1] + 3.29*x[2] + 2.74*x[3] <= 45)
m.addConstr(5.22*x[0] + 1.67*x[1] + 3.29*x[2] <= 51)
m.addConstr(5.22*x[0] + 2.74*x[3] + 4.63*x[4] <= 66)
m.addConstr(5.22*x[0] + 3.29*x[2] + 4.63*x[4] <= 54)
m.addConstr(1.67*x[1] + 2.74*x[3] + 4.63*x[4] <= 67)
m.addConstr(5.22*x[0] + 1.67*x[1] + 2.74*x[3] <= 81)
m.addConstr(3.29*x[2] + 2.74*x[3] + 4.63*x[4] <= 42)
m.addConstr(5.22*x[0] + 1.67*x[1] + 3.29*x[2] + 2.74*x[3] + 4.63*x[4] <= 42)


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    for v in m.getVars():
        print(f"{v.varName}: {v.x}")
    print(f"Obj: {m.objVal}")
elif m.status == gp.GRB.INFEASIBLE:
    print("The problem is infeasible.")
else:
    print(f"Optimization ended with status {m.status}")

```
