UVA1336FixingTheGreatWall

//UVA1336FixingTheGreatWall
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1000 + 5;
const double INF = 1e30;
double sum_d[maxn], d[maxn][maxn][2];
int n;
char vis[maxn][maxn][2]; 
double v, x; 
struct tofix {
	double location, cost, delta;
	bool operator < (const tofix& rhs) const {
	    return location < rhs.location;
	}
}fix[maxn];
double spend(double x, double y, int i, int j) {
	double start = 0;
	if(i == 1 && j == n) return 0;
	if(i >= 0 && j >= 0) start += sum_d[j] - sum_d[i - 1]; 
	return (sum_d[n] - start) * fabs(x - y) / v;
} 
double dp(int i, int j, int k) {
	if(i == 1 && j == n) return 0;
	double& ans = d[i][j][k];
	if(vis[i][j][k]) return ans;
	vis[i][j][k] = true;
	ans = INF;
	double x = (k == 0) ? fix[i].location : fix[j].location;
	if(i > 1) ans = min(ans, dp(i - 1, j, 0) + spend(x, fix[i - 1].location, i, j));//向左走 
	if(j < n) ans = min(ans, dp(i, j + 1, 1) + spend(x, fix[j + 1].location, i, j));//向右走 
	return ans; 
}
int main() {
	
	while(scanf("%d%lf%lf", &n, &v, &x) == 3 && n && v && x) {
		memset(vis, 0, sizeof(vis));
		memset(d, 0, sizeof(d));
		double tot = 0;
		for(int i = 1; i <= n; i++) {
		    scanf("%lf%lf%lf", &fix[i].location, &fix[i].cost, &fix[i].delta); 
		    tot += fix[i].cost;
		}
		fix[0].location = -INF;
		fix[0].cost = fix[n + 1].cost = fix[0].delta = fix[n + 1].delta = 0;
		fix[n + 1].location = INF;
		sort(fix + 1, fix + n + 1);
		memset(sum_d, 0, sizeof(sum_d));
		for(int i = 1; i <= n; i++) sum_d[i] += sum_d[i - 1] + fix[i].delta; 
		double ans = INF;
		for(int i = 1; i <= n + 1; i++) {
			if(fix[i - 1].location < x && fix[i].location > x) {//找到robot的初位置 
				if(i > 1) ans = min(ans, dp(i - 1, i - 1, 0) + spend(x, fix[i - 1].location, -1, -1));//决策,第一步向左走 
				if(i <= n) ans = min(ans, dp(i, i, 0) + spend(x, fix[i].location, -1, -1)); //同理于上 
			}
		}
		printf("%.0lf\n", floor(ans + tot));
	}
	return 0;
} 
/*
3 1 1000
1010 0 100
998 0 300
996 0 3
3 1 1000
1010 0 100
998 0 3
996 0 3
0 0 0
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>