```python
import gurobipy as gp

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

# Create variables
ringo = m.addVar(name="ringo")
jean = m.addVar(name="jean")
hank = m.addVar(name="hank")
george = m.addVar(name="george")
laura = m.addVar(name="laura")
bobby = m.addVar(name="bobby")

# Set objective function
m.setObjective(2 * ringo + 4 * jean + hank + 2 * george + 8 * laura + 6 * bobby, gp.GRB.MINIMIZE)

# Resource data
resource_data = {
    'r0': {'description': 'computer competence rating', 'upper_bound': 374, 'x0': 15.73, 'x1': 4.24, 'x2': 13.87, 'x3': 3.38, 'x4': 12.37, 'x5': 13.37},
    'r1': {'description': 'productivity rating', 'upper_bound': 462, 'x0': 5.0, 'x1': 7.79, 'x2': 16.3, 'x3': 9.14, 'x4': 3.59, 'x5': 16.66},
    'r2': {'description': 'dollar cost per hour', 'upper_bound': 445, 'x0': 10.69, 'x1': 1.53, 'x2': 10.54, 'x3': 7.47, 'x4': 6.51, 'x5': 17.9},
    'r3': {'description': 'paperwork competence rating', 'upper_bound': 367, 'x0': 2.46, 'x1': 16.0, 'x2': 15.12, 'x3': 6.52, 'x4': 4.02, 'x5': 1.59}
}

vars = [ringo, jean, hank, george, laura, bobby]

# Add constraints based on the provided input
m.addConstr(15.73 * ringo + 4.24 * jean >= 40)
m.addConstr(15.73 * ringo + 12.37 * laura >= 28)
m.addConstr(4.24 * jean + 12.37 * laura >= 21)
m.addConstr(13.87 * hank + 13.37 * bobby >= 58)
m.addConstr(3.38 * george + 13.37 * bobby >= 46)
m.addConstr(13.87 * hank + 3.38 * george >= 30)
m.addConstr(15.73 * ringo + 3.38 * george >= 29)
m.addConstr(4.24 * jean + 3.38 * george >= 61)
m.addConstr(13.87 * hank + 12.37 * laura >= 42)
m.addConstr(15.73 * ringo + 13.87 * hank >= 21)
m.addConstr(ringo >= bobby)


for resource_key, resource_info in resource_data.items():
    coefficients = [resource_info[f'x{i}'] for i in range(len(vars))]
    m.addConstr(gp.LinExpr(coefficients, vars) <= resource_info['upper_bound'])


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Optimal objective:', m.objVal)
    for v in m.getVars():
        print(f'{v.varName}: {v.x}')
elif m.status == gp.GRB.INFEASIBLE:
    print('Model is infeasible')
else:
    print('Optimization ended with status:', m.status)

```