It turns out that the algorithm I was trying works for the minimization of the sum $\sum_{j=1}^m F(r_{k_{j-1}+1}+\dots+r_{k_j})$ (we put $k_0=0$) for an arbitrary strictly convex function $F$, so I'll describe it and you'll be able to choose your $F$ later. I personally like $F(t)=1/t$ (minimizing the total height), but for reasonable $r_i$, your $F(t)=t^2$ works pretty well too and the corresponding partitions are fairly close.
The idea is the same dynamic programming. We will compute the best partition of all initial segments $[1,k]$ ($k=0,\dots,n$ into $j=1,\dots,m$ pieces to minimize the sum of the corresponding $F$'s. Let $N(k,j)$ be the corresponding minimum. Put $x_i=r_1+\dots+r_i$ ($i=0,\dots,n$).
We trivially have $N(k,1)=F(r_1+\dots+r_k)$.
Now, for $j\ge 2$, we have the recursion
$$
N(k,j)=\min_{0\le i\le k}[N(i,j-1)+F(x[k]-x[i])]\,.
$$
However, if we run it just like that, it will have the running time $n^2m$, which is a bit too much, though even that is sort of tolerable in your range. To accelerate, let us notice the following thing.
If for some fixed $j$ and $k$, the minimum in the recursion is achieved at $i=I$, then for the same $j$ and $k'>k$, the minimum is achieved at $i\ge I$.
Indeed, for $i<I$, we have
$$
N(I,j-1)-N(i,j-1)\le F(x_k-x_i)-F(x_k-x_I)\le
F(x_{k'}-x_i)-F(x_{k'}-x_I)
$$
(here the first inequality is just a restatement of the condition that the minimum for $k,j$ is achieved at $i=I$, and the second inequality follows from the convexity of $F$).
Thus, we can run the recursion not in the natural order $k=1,2,3,\dots$, but in the order of the highest power of $2$ in $k$. So, once we know the best $i$ for the adjacent multiples of $2^q$, we can search for the best $i$ for the multiple of $2^{q-1}$ in the middle only between these two values. That ensures that we check at most $2n$ values to find $N(k,j)$ for all odd multiples of the same power of $2$ regardless of what that power of $2$ is, thus giving the running time $n\log n$ for each $j$.
The rest is absolutely standard for the dynamic programming approach, so I'll just post the code. I programmed in Asymptote (which allowed me to see the resulting geometric layout easily). If translation to JavaScript presents any difficulties for you, just let me know and I'll do it myself. If the time is still unsatisfactory, let me know and I'll think more.
int n=300, m=30;
srand(seconds());
real[] r,x;
r[0]=0;
for(int k=1;k<=n;++k) r[k]=0.3+2*unitrand();
for(int k=rand()%7+1;k<n;k+=rand()%7+1) r[k]=10*unitrand();
x[0]=0; for(int k=1;k<=n;++k) x[k]=x[k-1]+r[k];
real F(real t)
{
//return t^2;
return 1/(t+0.0001*x[n]/n);
}
real[] S,T;
int[][] v;
real t=0;
for(int k=0;k<=n;++k) {t+=r[k]; S[k]=F(t);}
int count=0;
for(int j=2; j<=m;++j)
{
int[] q; q[0]=0;
int K=floor(log(n)/log(2)+1);
for(int qq=2^K; qq>0; qq=quotient(qq,2))
for(int k=qq;k<=n;k+=2*qq)
{
int imin=q[k-qq];
int imax=k; if(k+qq<=n) imax=min(k,q[k+qq]);
real M=-1;
for(int i=imin;i<=imax ;++i)
{
++count;
real MM=S[i]+F(x[k]-x[i]);
if(MM<M || M<0) {M=MM; q[k]=i;}
}
T[k]=M;
}
T[0]=F(0);
S=copy(T);
v[j]=copy(q);
}
int[] kk; kk[m]=n; kk[0]=0; for(int j=m; j>=2; --j) kk[j-1]=v[j][kk[j]];
write(kk);
write(count, S[n]); pause();
size(400);
real H=0;
for(int mm=1;mm<=m;++mm)
{
real h=1/(x[kk[mm]]-x[kk[mm-1]]); H-=h;
for(int j=kk[mm-1]; j<kk[mm]; ++j)
draw(box((h*(x[j]-x[kk[mm-1]]),H),(h*(x[j+1]-x[kk[mm-1]]),H+h)));
}