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

```python
import gurobipy as gp

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

# Create variables
x0 = m.addVar(vtype=gp.GRB.INTEGER, name="airborne_infantry_companies")
x1 = m.addVar(vtype=gp.GRB.INTEGER, name="reconnaissance_troops")
x2 = m.addVar(vtype=gp.GRB.INTEGER, name="medical_platoons")
x3 = m.addVar(vtype=gp.GRB.INTEGER, name="military_intelligence_companies")

# Set objective function
m.setObjective(8.45 * x0 + 6.05 * x1 + 1.68 * x2 + 9.56 * x3, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(4.55 * x0 + 9.92 * x1 + 1.03 * x2 + 8.91 * x3 <= 135, "Total_Logistics_Footprint")
m.addConstr(4.55 * x0 + 1.03 * x2 >= 19, "Footprint_x0_x2_min")
m.addConstr(9.92 * x1 + 8.91 * x3 >= 14, "Footprint_x1_x3_min")
m.addConstr(9.92 * x1 + 1.03 * x2 >= 29, "Footprint_x1_x2_min")
m.addConstr(4.55 * x0 + 8.91 * x3 >= 22, "Footprint_x0_x3_min")
m.addConstr(1.03 * x2 + 8.91 * x3 >= 25, "Footprint_x2_x3_min")
m.addConstr(9.92 * x1 + 1.03 * x2 + 8.91 * x3 >= 32, "Footprint_x1_x2_x3_min")
m.addConstr(9.92 * x1 + 1.03 * x2 <= 71, "Footprint_x1_x2_max")
m.addConstr(4.55 * x0 + 8.91 * x3 <= 37, "Footprint_x0_x3_max")
m.addConstr(1.03 * x2 + 8.91 * x3 <= 129, "Footprint_x2_x3_max")
m.addConstr(4.55 * x0 + 1.03 * x2 + 8.91 * x3 <= 68, "Footprint_x0_x2_x3_max")
m.addConstr(4.55 * x0 + 9.92 * x1 + 1.03 * x2 + 8.91 * x3 <= 68, "Total_Footprint_max")


# Optimize model
m.optimize()

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

```
