## Problem Formulation

The paint manufacturer's problem can be formulated as a linear programming (LP) problem. The goal is to maximize profit by deciding how much of each paint product to produce given the constraints on dye and filler availability.

### Decision Variables

Let \(x_1\), \(x_2\), and \(x_3\) represent the amount of oil painting, acrylic painting, and watercolor painting produced in kilograms, respectively.

### Objective Function

The profit per kg for selling each type of paint is given as $150 for oil paintings, $180 for acrylic paintings, and $220 for watercolor paintings. The objective function to maximize profit (\(P\)) is:

\[P = 150x_1 + 180x_2 + 220x_3\]

### Constraints

1. **Dye Constraint**: The manufacturer has 350 kg of dye available. Producing 1 kg of oil paintings requires 6.5 kg of dye, 1 kg of acrylic paintings requires 8 kg of dye, and 1 kg of watercolor paintings requires 16 kg of dye. Therefore, the dye constraint is:

\[6.5x_1 + 8x_2 + 16x_3 \leq 350\]

2. **Filler Constraint**: The manufacturer has 250 kg of filler available. Producing 1 kg of oil paintings requires 15 kg of filler, 1 kg of acrylic paintings requires 12 kg of filler, and 1 kg of watercolor paintings requires 5 kg of filler. Therefore, the filler constraint is:

\[15x_1 + 12x_2 + 5x_3 \leq 250\]

3. **Non-Negativity Constraints**: The amount of each paint product produced cannot be negative:

\[x_1 \geq 0, x_2 \geq 0, x_3 \geq 0\]

## Gurobi Code

```python
import gurobi

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

    # Decision variables
    x1 = model.addVar(lb=0, name="oil_painting")
    x2 = model.addVar(lb=0, name="acrylic_painting")
    x3 = model.addVar(lb=0, name="watercolor_painting")

    # Objective function
    model.setObjective(150*x1 + 180*x2 + 220*x3, gurobi.GRB.MAXIMIZE)

    # Dye constraint
    model.addConstr(6.5*x1 + 8*x2 + 16*x3 <= 350, name="dye_constraint")

    # Filler constraint
    model.addConstr(15*x1 + 12*x2 + 5*x3 <= 250, name="filler_constraint")

    # Optimize the model
    model.optimize()

    # Print the status
    if model.status == gurobi.GRB.Status.OPTIMAL:
        print("Optimal solution found.")
        print(f"Oil Painting: {x1.varValue} kg")
        print(f"Acrylic Painting: {x2.varValue} kg")
        print(f"Watercolor Painting: {x3.varValue} kg")
        print(f"Max Profit: ${model.objVal:.2f}")
    else:
        print("No optimal solution found.")

solve_paint_manufacturer_problem()
```