## Problem Description and Formulation

Maximus Ltd wants to maximize the viewership of their new Max product by advertising on billboards, podcasts, and merchandises. Each advertising medium has a different cost and expected viewership:

- Billboards: $750 per ad, reaching 40,000 viewers
- Podcasts: $1,000 per ad, reaching 10,000 viewers
- Merchandises: $300 per ad, reaching 2,000 viewers

There are constraints on the advertising strategy:
1. The billboard provider limits the number of ads from the same company to 3.
2. At most 40% of the total number of ads can occur on merchandises.
3. At least 25% of the total number of ads should occur on podcasts.
4. The company has a budget of $20,000.

## Mathematical Formulation

Let \(B\), \(P\), and \(M\) be the number of ads on billboards, podcasts, and merchandises, respectively.

- Objective function (Maximize viewership): \(40,000B + 10,000P + 2,000M\)
- Constraints:
  1. \(B \leq 3\)
  2. \(M \leq 0.4(B + P + M)\)
  3. \(P \geq 0.25(B + P + M)\)
  4. \(750B + 1000P + 300M \leq 20,000\)
  5. \(B, P, M \geq 0\) and are integers (since partial ads are not possible)

## Gurobi Code

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

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

# Variables
B = model.addVar(lb=0, ub=3, vtype=GRB.INTEGER, name="Billboards")
P = model.addVar(lb=0, vtype=GRB.INTEGER, name="Podcasts")
M = model.addVar(lb=0, vtype=GRB.INTEGER, name="Merchandises")

# Objective function: Maximize viewership
model.setObjective(40000*B + 10000*P + 2000*M, GRB.MAXIMIZE)

# Constraints
model.addConstr(B <= 3, name="Billboard_Limit")
model.addConstr(M <= 0.4*(B + P + M), name="Merchandise_Limit")
model.addConstr(P >= 0.25*(B + P + M), name="Podcast_Minimum")
model.addConstr(750*B + 1000*P + 300*M <= 20000, name="Budget_Constraint")

# Solve the model
model.optimize()

# Print the results
if model.status == GRB.OPTIMAL:
    print("Optimal Solution:")
    print(f"Billboards: {B.varValue}")
    print(f"Podcasts: {P.varValue}")
    print(f"Merchandises: {M.varValue}")
    print(f"Max Viewership: {model.objVal}")
else:
    print("No optimal solution found")
```