Here's the formulation of the linear program and the Gurobi code to solve it:

**Decision Variables:**

* `x`: Number of engineers hired
* `y`: Number of interns hired

**Objective Function:**

Minimize total weekly wages: `3000x + 750y`

**Constraints:**

* **Total Workers:** `x + y >= 100`
* **Minimum Interns:** `y >= 20`
* **Intern to Engineer Ratio:** `y >= (1/3)x`
* **Maximum Payroll:** `3000x + 750y <= 200000`
* **Non-negativity:** `x >= 0`, `y >= 0`


```python
import gurobipy as gp
from gurobipy import GRB

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

# Create variables
x = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="engineers") # Number of engineers
y = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="interns")   # Number of interns

# Set objective function
m.setObjective(3000*x + 750*y, GRB.MINIMIZE)

# Add constraints
m.addConstr(x + y >= 100, "total_workers")
m.addConstr(y >= 20, "min_interns")
m.addConstr(y >= (1/3)*x, "intern_engineer_ratio")
m.addConstr(3000*x + 750*y <= 200000, "max_payroll")

# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print(f"Optimal Solution Found:")
    print(f"Number of Engineers (x): {x.x}")
    print(f"Number of Interns (y): {y.x}")
    print(f"Minimum Weekly Wages: ${m.objVal}")
elif m.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization terminated with status: {m.status}")

```
