dynamic(i, j, k)中i代表已修好的部分的左端点,j代表已修好的部分的右端点, k==0代表此时机器人在i点, k==1代表此时机器人在j点。
如果k = 0, 那么机器人一定是修好i+1到j的所有点,再到i点修好了i点处的缺口,所以k=0时的转移方程为
dynamic(i, j, 0) = min(dynamic(i+1, j, 0) + 代价, dynamic(i+1, j, 1) + 代价)。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define INF 0x3f3f3f3f
typedef struct nod{
double x;
double imm;
double cost;
}nod;
nod node[10050];
double dp[10050][1005][2];
int vis[10050][1005][2];
double cost[20000];
int n;
double x0, v;
bool cmp(nod a, nod b){
return a.x < b.x;
}
double dynamic(int i, int j, int k)
{
if(vis[i][j][k])
return dp[i][j][k];
double& ans = dp[i][j][k];
ans = INF;
if(i == j)
{
if(fabs(node[i].x-x0)<1e-4)
{
vis[i][j][k] = 1;
ans = 0;
return 0;
}
else
{
vis[i][j][k] = 1;
ans = INF;
return INF;
}
}
if(!k)
{
ans = min(ans, dynamic(i+1,j,0) + (node[i+1].x-node[i].x)/v*(cost[i]+cost[n]-cost[j]) + node[i].imm);
ans = min(ans, dynamic(i+1,j,1) + (node[j].x-node[i].x)/v*(cost[i]+cost[n]-cost[j]) + node[i].imm);
//printf("test%.3lf %.3lf\n",dynamic(i+1,j,0),(node[j].x-node[i].x)/v*(cost[i]+cost[n]-cost[j]) + node[i].imm);
}
if(k)
{
ans = min(ans, dynamic(i,j-1,0) + (node[j].x-node[i].x)/v*(cost[i-1]+cost[n]-cost[j-1]) + node[j].imm);
ans = min(ans, dynamic(i,j-1,1) + (node[j].x-node[j-1].x)/v*(cost[i-1]+cost[n]-cost[j-1]) + node[j].imm);
}
vis[i][j][k] = 1;
return ans;
}
int main()
{
//freopen("ztest.txt","r",stdin);
//freopen("zans.txt","w",stdout);
while(scanf("%d%lf%lf",&n, &v, &x0) == 3)
{
memset(vis, 0, sizeof(vis));
memset(cost, 0, sizeof(cost));
if(n == 0) // 注意break条件的写法
if(fabs(v-0)<=1e-4) //
if(fabs(x0-0)<=1e-4) //
break;
for(int i = 1; i <= n; i++)
scanf("%lf%lf%lf", &node[i].x, &node[i].imm, &node[i].cost);
n++;
node[n].x = x0;
node[n].imm = 0;
node[n].cost = 0;
sort(node+1, node+1+n, cmp);
double temp = 0;
cost[0] = 0;
for(int i = 1; i <= n; i++)
{
temp += node[i].cost;
cost[i] = temp;
}
printf("%.0lf\n", floor(min(dynamic(1, n, 0), dynamic(1, n, 1))));
}
return 0;
}