## Step 1: Define the symbolic variables
Let's define the symbolic variables as follows:
- $x_1$ represents the number of cleaners.
- $x_2$ represents the number of receptionists.

## Step 2: Formulate the objective function
The objective is to minimize the weekly wage bill. Cleaners earn $500 per week and receptionists earn $350 per week. Therefore, the objective function can be represented as:
\[ \text{Minimize} \quad 500x_1 + 350x_2 \]

## 3: Define the constraints
Based on the problem description, we have the following constraints:
1. The hotel requires a minimum of 100 workers: $x_1 + x_2 \geq 100$
2. At least 20 workers must be receptionists: $x_2 \geq 20$
3. The number of receptionists should be at least a third of the number of cleaners: $x_2 \geq \frac{1}{3}x_1$
4. The hotel wants to keep the weekly wage bill below $30,000: $500x_1 + 350x_2 \leq 30000$

## 4: Convert the problem into a symbolic representation
The symbolic representation of the problem is:
```json
{
    'sym_variables': [('x1', 'cleaners'), ('x2', 'receptionists')],
    'objective_function': '500*x1 + 350*x2',
    'constraints': [
        'x1 + x2 >= 100',
        'x2 >= 20',
        'x2 >= (1/3)*x1',
        '500*x1 + 350*x2 <= 30000'
    ]
}
```

## 5: Implement the problem in Gurobi code
Now, let's implement this problem in Gurobi using Python:
```python
import gurobi

def hotel_staffing_problem():
    # Create a new model
    model = gurobi.Model()

    # Define the variables
    x1 = model.addVar(name='cleaners', lb=0, vtype=gurobi.GRB.INTEGER)  # Number of cleaners
    x2 = model.addVar(name='receptionists', lb=0, vtype=gurobi.GRB.INTEGER)  # Number of receptionists

    # Objective function: Minimize the wage bill
    model.setObjective(500*x1 + 350*x2, gurobi.GRB.MINIMIZE)

    # Constraints
    model.addConstr(x1 + x2 >= 100, name='min_workers')
    model.addConstr(x2 >= 20, name='min_receptionists')
    model.addConstr(x2 >= (1/3)*x1, name='receptionists_to_cleaners_ratio')
    model.addConstr(500*x1 + 350*x2 <= 30000, name='wage_bill')

    # Optimize the model
    model.optimize()

    # Print the results
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal number of cleaners: {x1.varValue}")
        print(f"Optimal number of receptionists: {x2.varValue}")
        print(f"Minimum wage bill: ${model.objVal:.2f}")
    else:
        print("The model is infeasible.")

hotel_staffing_problem()
```