To solve the given optimization problem, we need to formulate it as a linear programming (LP) or mixed-integer linear programming (MILP) problem since some of the variables are restricted to whole numbers. The objective function and constraints will be translated into Gurobi code.

The problem involves minimizing an objective function subject to various constraints related to sustainability scores, dollar costs, and other limitations on the quantities of lanyards, postage stamps, and cans of coffee.

First, let's break down the given information:

- **Variables**:
  - `lanyards` (x0)
  - `postage_stamps` (x1)
  - `cans_of_coffee` (x2)

- **Objective Function**: Minimize \(7.8 \times x0 + 3.65 \times x1 + 4.87 \times x2\)

- **Constraints**:
  1. Sustainability score constraints:
     - \(17x0 + 6x2 \geq 20\)
     - \(5x1 + 6x2 \geq 12\)
     - \(17x0 + 5x1 + 6x2 \geq 20\)
     - \(17x0 + 5x1 + 6x2 \leq 39\)
  2. Cost constraints:
     - \(12x0 + 8x2 \geq 54\)
     - \(11x1 + 8x2 \geq 52\)
     - \(12x0 + 11x1 + 8x2 \geq 52\)
     - \(12x0 + 8x2 \leq 151\)
     - \(12x0 + 11x1 \leq 65\)
     - \(11x1 + 8x2 \leq 101\)
  3. Other constraints:
     - \(x0 - 3x1 \geq 0\)

Given the nature of the problem, we will use Gurobi's Python interface to formulate and solve this MILP.

```python
from gurobipy import *

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

# Define variables as integers
lanyards = m.addVar(vtype=GRB.INTEGER, name="lanyards")
postage_stamps = m.addVar(vtype=GRB.INTEGER, name="postage_stamps")
cans_of_coffee = m.addVar(vtype=GRB.INTEGER, name="cans_of_coffee")

# Set the objective function
m.setObjective(7.8*lanyards + 3.65*postage_stamps + 4.87*cans_of_coffee, GRB.MINIMIZE)

# Add constraints
m.addConstr(17*lanyards + 6*cans_of_coffee >= 20)
m.addConstr(5*postage_stamps + 6*cans_of_coffee >= 12)
m.addConstr(17*lanyards + 5*postage_stamps + 6*cans_of_coffee >= 20)
m.addConstr(17*lanyards + 5*postage_stamps + 6*cans_of_coffee <= 39)

m.addConstr(12*lanyards + 8*cans_of_coffee >= 54)
m.addConstr(11*postage_stamps + 8*cans_of_coffee >= 52)
m.addConstr(12*lanyards + 11*postage_stamps + 8*cans_of_coffee >= 52)

m.addConstr(12*lanyards + 8*cans_of_coffee <= 151)
m.addConstr(12*lanyards + 11*postage_stamps <= 65)
m.addConstr(11*postage_stamps + 8*cans_of_coffee <= 101)

m.addConstr(lanyards - 3*postage_stamps >= 0)

# Optimize the model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Lanyards: {lanyards.X}")
    print(f"Postage Stamps: {postage_stamps.X}")
    print(f"Cans of Coffee: {cans_of_coffee.X}")
else:
    print("No optimal solution found.")
```