https://vjudge.net/problem/UVA-1336
Obviously the best way to move some must be left to go, goes a right, then goes a left, then go for some right ...... (or vice versa)
In any case it will be the first to fix the middle, so consider the interval dp
$ F_ {i, j, 0/1} $ I $ represents mended \ when rightarrow j $, with minimum costs (the cost calculated in advance note)
Pretreatment at $ cl_ {i, j} (i \ leq j) $ $ represents the starting repair costs from $ J $ $ i
$ Cr_ {i, j} (i \ geq j) $ $ I $ departing from the repair costs $ $ J
Then is transferred (but it is still good to think), because the decision set is not reduced, it is possible to use a mark recorded at a minimum, $ O (1) $ Transfer
#include<bits/stdc++.h> using namespace std; const int N=1005; const double inf=1000000000.0,eps=0.000001; int n,v,x,st; struct node{int c,d,x;} sec[N]; double f[N][N][2],cl[N][N],cr[N][N]; double sum[N],min0[N],min1[N],bs; void clear() { st=0,bs=0; for(int i=0;i<N;++i) { sum[i]=0,cl[i][i]=0; min0 [i] = min-1 [i] = inf; } } double tme(int a,int b) {return (double)abs(sec[a].x-sec[b].x)/(double)v;} bool cmp(node a,node b) {return a.x<b.x;} int main() { while (scanf("%d%d%d", &n, &v, &x)==3 && n) { if(!n && !v && !x) return 0; clear(); for(int i=1;i<=n;++i) scanf("%d%d%d",&sec[i].x,&sec[i].c,&sec[i].d); sort(sec+1,sec+n+1,cmp); sec[n+1].x=x+1; for(int i=1;i<=n+1;++i) if(sec[i].x>x) {st=i-1;break;} for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) cl[i][j]=cl[i][j-1]+tme(i,j)*sec[j].d; for(int i=1;i<=n;++i) for(int j=i-1;j>=1;--j) cr[i][j]=cr[i][j+1]+tme(i,j)*sec[j].d; for(int i=1;i<=n;++i) sum[i]=sum[i-1]+sec[i].d,bs+=sec[i].c; if(!st) { printf("%.0lf\n",floor(bs+cl[1][n]+1.0*(sec[1].x-x)/(1.0*v)*sum[n]+eps)); continue; } if(st==n) { printf("%.0lf\n",floor(bs+cr[n][1]+1.0*(x-sec[n].x)/(1.0*v)*sum[n]+eps)); continue; } f[st][st][0]=f[st][st][1]=1.0*(x-sec[st].x)/(1.0*v)*sum[n]; f[st+1][st+1][0]=f[st+1][st+1][1]=1.0*(sec[st+1].x-x)/(1.0*v)*sum[n]; min0[st]=min1[st]=f[st][st][0]; min0[st+1]=min1[st+1]=f[st+1][st+1][0]; for(int i=2;i<=n;++i) for(int j=max(1,st-i+1);j<=st+1 && i+j-1<=n;++j) { int l=j,r=j+i-1; double pre=sum[n]-sum[r]+sum[l-1]; f[l][r][0]=min0[r]+cr[r][l]+tme(r,l)*pre; f[l][r][1]=min1[l]+cl[l][r]+tme(r,l)*pre; min0 [r] = min (min0 [r], b [l] [s] [ 1 ] - cr [s] [l]); min1[l]=min(min1[l],f[l][r][0]-cl[l][r]); //cout<<l<<" "<<r<<" "<<f[l][r][0]<<" "<<f[l][r][1]<<endl; } printf("%.0lf\n",floor(min(f[1][n][0],f[1][n][1])+bs+eps)); } return 0; }