Starting maxSpeed should be about 6.28171069
The naive approach isn't terribly difficult, but it's a bit tedious. I'm using "naive" here to mean "ignoring that the actual time spent prior to getting a boost token will vary based on frame rate", and "we assume runner reaches max speed after each boost, prior to the next boost". If you need better than that, you'll need to go beyond what I do here and add per-frame bookkeeping.
Suppose you think of your track as numTokens+1 sections. Each section has a time to traverse based on the player's acceleration and max speed in that section.
Working from formulas for distance-acceleration explanation (I grabbed them from http://www.dummies.com/education/science/physics/how-to-calculate-time-and-distance-from-acceleration-and-velocity/ ) you can work out how long each section has to take to hit the target time of 9.4, and from that, work out the starting maxSpeed you'd need.
Two formula of interest pulled from the above link:
t = ( v_f - v_i ) / a (time to reach a given speed from a start speed with a given acceleration)
s = v_i*t + 0.5*a*t^2 (how much distance was traveled during that acceleration)
and I suppose we can include the equation Stephan mentioned:
speed = distance/time
More Variables, Maestro!
Let's define a few variables of interest, using _j to denote values related to the jth section of track:
startSpeed_j is the speed we had coming into section j
maxSpeed_j is the
maxSpeed we can reach in section j, a function of our initial
maxSpeed + numTokens * tokenIncreaseSpeed
accelTime_j is how long it takes to accelerate to maxSpeed for section j
accelDist_j is the distance traveled during acceleration
cruiseDist_j is how much distance remains in a section after
cruiseTime_j is how long we spend at maxSpeed before we reach the next boost
totalTime_j is how long the runner spends in the section
overallTime_j is how long it took the runner to get from the race start to the end of section j
So using the above formulas and variables in a per-section way, we get:
accelTime_j = (maxSpeed_j - startSpeed_j) / acceleration
accelDist_j = startSpeed_j * accelTime_j + (1/2) * acceleration * accelTime_j * accelTime_j
Then with these, we can figure out how much distance remains after acceleration:
cruiseDist_j = tokenDistribution - accelDist_j
cruiseTime_j = cruiseDist_j / maxSpeed_j
And from these we can calculate how long the section takes to run (though we need a special case for the first section):
totalTime_j = accelTime_j + cruiseTime_j
overallTime_j = overallTime_(j-1) + totalTime_j
You could flip all this around to solve for the starting maxSpeed value, but unless you need that to be adjustable real-time in your game, I'd probably just solve it by trial and error.
I made a google doc spreadsheet that I used to solve this, which you can find and make a copy of here:
The sheet supports tweaking of the initial parameters (up to 50 numTokens, above that will you'll have to do some copy-pasting), and has the starting maxSpeed value I found: 6.28171069
Hope this helps!