## Symbolic Representation

The problem can be converted into a symbolic representation as follows:

* Variables: 
  - `x1`: acres of guavas
  - `x2`: acres of mangos

* Objective Function: Maximize $300x1 + 500x2$

* Constraints:
  - $x1 + x2 \leq 100$ (total acres of land)
  - $x2 \leq 2x1$ (at most 2 times the amount of mangos as guavas)
  - $x1 \geq 20$ (at least 20 acres of guavas)
  - $x2 \geq 40$ (at least 40 acres of mangos)
  - $x1, x2 \geq 0$ (non-negativity constraint, implicitly assumed)

The symbolic representation can be summarized as:
```json
{
    'sym_variables': [('x1', 'acres of guavas'), ('x2', 'acres of mangos')],
    'objective_function': '300*x1 + 500*x2',
    'constraints': [
        'x1 + x2 <= 100',
        'x2 <= 2*x1',
        'x1 >= 20',
        'x2 >= 40'
    ]
}
```

## Gurobi Code

Here is the Gurobi code in Python:
```python
import gurobipy as gp

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

# Define variables
x1 = m.addVar(name="guavas", lb=0)
x2 = m.addVar(name="mangos", lb=0)

# Objective function
m.setObjective(300*x1 + 500*x2, gp.GRB.MAXIMIZE)

# Constraints
m.addConstr(x1 + x2 <= 100, name="land_constraint")
m.addConstr(x2 <= 2*x1, name="mango_to_guava_ratio")
m.addConstr(x1 >= 20, name="guava_minimum")
m.addConstr(x2 >= 40, name="mango_minimum")

# Solve the model
m.optimize()

# Print the solution
if m.status == gp.GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Acres of guavas: {x1.varValue}")
    print(f"Acres of mangos: {x2.varValue}")
    print(f"Maximum profit: {m.objVal}")
else:
    print("No optimal solution found.")
```