To solve the given optimization problem, we first need to translate the natural language description into a symbolic representation. This involves defining variables for the quantities involved and formulating the objective function and constraints in terms of these variables.

Let's denote:
- $x_1$ as the number of shampoo bottles filled,
- $x_2$ as the number of conditioner bottles filled.

The profit per shampoo bottle is $5, and the profit per conditioner bottle is $6. The objective is to maximize profit, so the objective function can be represented as:
\[ \text{Maximize: } 5x_1 + 6x_2 \]

Given constraints are:
- Each shampoo bottle takes 3 minutes to fill.
- Each conditioner bottle takes 4 minutes to fill.
- The company must fill at least 50 shampoo bottles and at least 30 conditioner bottles.
- The total available time is 300 minutes.

Thus, the constraints can be formulated as follows:
1. Time constraint: \(3x_1 + 4x_2 \leq 300\)
2. Minimum shampoo bottles: \(x_1 \geq 50\)
3. Minimum conditioner bottles: \(x_2 \geq 30\)

Also, since the number of bottles cannot be negative:
4. Non-negativity constraints: \(x_1 \geq 0\) and \(x_2 \geq 0\)

However, given that \(x_1\) and \(x_2\) must be at least 50 and 30 respectively, the non-negativity constraints are implicitly satisfied.

The symbolic representation of the problem is thus:
```json
{
  'sym_variables': [('x1', 'number of shampoo bottles'), ('x2', 'number of conditioner bottles')],
  'objective_function': '5*x1 + 6*x2',
  'constraints': ['3*x1 + 4*x2 <= 300', 'x1 >= 50', 'x2 >= 30']
}
```

To solve this problem using Gurobi in Python, we can use the following code:

```python
from gurobipy import *

# Create a new model
m = Model("Shampoo_Conditioner_Optimization")

# Create variables
x1 = m.addVar(lb=50, vtype=GRB.INTEGER, name="shampoo_bottles")
x2 = m.addVar(lb=30, vtype=GRB.INTEGER, name="conditioner_bottles")

# Set the objective function
m.setObjective(5*x1 + 6*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(3*x1 + 4*x2 <= 300, "time_constraint")

# Optimize model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution: {x1.varName} = {x1.x}, {x2.varName} = {x2.x}")
    print(f"Maximum profit: {m.objVal}")
else:
    print("No optimal solution found")
```