区间dp给我的印象一直是O(n3)的
做到这题才发现自己理解的偏差
题解参考:原作者
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
const int maxn = 1005;
using namespace std;
double dp[maxn][maxn][2];
double sum[maxn];
struct node{
double x,c,d;
node(){}
node(double xx, double cc, double dd):x(xx),c(cc),d(dd){}
bool operator < (const node & p) const{
return x < p.x;
}
}plot[maxn];
double cal(int l, int r){
return sum[r] - sum[l-1];
}
int main(){
int n;
double v,x;
while(scanf("%d%lf%lf",&n,&v,&x) == 3 && n){
for(int i=1; i<=n; i++)
scanf("%lf%lf%lf",&plot[i].x,&plot[i].c,&plot[i].d);
n++;
sum[0] = 0;
for(int i=1; i<=n; i++)
for(int j=i; j<=n; j++)
dp[i][j][0] = dp[i][j][1] = INF;
//memset(dp, INF, sizeof(dp);
plot[n].x = x;//插入初始位置
plot[n].c = plot[n].d = 0;
sort(plot+1,plot+1+n);
for(int i=1; i<=n; i++) sum[i] = sum[i-1] + plot[i].d;
for(int i=1; i<=n; i++)
if(plot[i].x == x) {
dp[i][i][0] = dp[i][i][1] = 0;
break;
}
for(int i=1; i<=n; i++){//区间长度
for(int j=1; j+i-1<=n; j++){//起点
int l = j;
int r = j+i-1;
double t = (plot[l].x - plot[l-1].x)/v;
dp[l-1][r][0] = min(dp[l-1][r][0],dp[l][r][0]+(cal(1,l-1)+cal(r+1,n))*t+plot[l-1].c);
t = (plot[r].x-plot[l-1].x)/v;
dp[l-1][r][0] = min(dp[l-1][r][0],dp[l][r][1]+(cal(1,l-1)+cal(r+1,n))*t+plot[l-1].c);
t = (plot[r+1].x - plot[r].x)/v;
dp[l][r+1][1] = min(dp[l][r+1][1],dp[l][r][1]+(cal(1,l-1)+cal(r+1,n))*t+plot[r+1].c);
t = (plot[r+1].x-plot[l].x)/v;
dp[l][r+1][1] = min(dp[l][r+1][1],dp[l][r][0]+(cal(1,l-1)+cal(r+1,n))*t+plot[r+1].c);
}
}
printf("%.lf\n",floor(min(dp[1][n][0],dp[1][n][1])));
}
}
/*
3 1 1000
1010 0 100
998 0 300
996 0 3
*/