//
// main.cpp
// uva 1336 - Fixing the Great Wall
/*
我们先按位置大小排序。
首先我们注意到:
对于 i ....x.....j,x表示现在的机器人的位置。
如果x现在在修复了i,那么位于x和i之间的所有位置都是已经修复好的了,因为我们当前已经到了i,那么我们就可以顺便修复了x和i之间的位置,这绝对不会增加最终的总费用。所以得出了一个结论。
最优的修复顺序满足,1---x之间的位置在最优解中的相对位置是相反的。而x---n之间的位置的相对位置是不变的。
有了这个结论我们可以想到解法了.
对于当前的位置我们有两个选择 1.修复当前位置右边的位置。
2.修复当前位置左边的位置。
设d[i][j][t]表示当前所在的位置为t,(t等于i或者j),且只考虑前i个,和第j个以及后面的位置,修理后面被破坏的区域需要的最少的钱。
这里t只为1或者0.0表示在左边,1表示字右边的节点上。
则有
d[i][j][0] = min(d[i][j][0] , d[i-1][j][0]+t[i-1][i] * c_all[i-1][j],d[i-1][j+1][1] + t[j][j+1]* c_all[i-1][j+1]);t[i][j]表示从i到j的时间。
同理可得出在t==1时的情况。
*/
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
#define ll long long
using namespace std ;
double d[1010][1010][2];
double v ;
double INF = 1000000000 ;
int c_all[1010][1010] ;
struct sec{
int pos , c,d ;
bool operator < (const sec &temp ) const{
return pos < temp.pos ;
} ;
};
sec wall[1010] ;
int n ;
double min(double a,double b)
{
return a >b ? b :a ;
}
double dp(int l , int r , int t)
{
if (d[l][r][t] >= 0 ) {
return d[l][r][t] ;
}
else{
double time ;
double& ans = d[l][r][t] ;
ans = INF ;
if (t == 0 ) {
if (l <= 1&& r == n + 1) {
return ans = 0 ;
}
if(l >1) {
time =((double )(wall[l].pos - wall[l-1].pos))/v ;
ans = min(ans , dp(l-1,r , 0) + time * c_all[l-1][r]) ;
}
if(r <=n ) {
time = ((double) (wall[r].pos - wall[l].pos))/v ; ;
ans = min(ans , dp(l-1, r, 1) + time * c_all[l-1][r]) ;
}
}
else{
if (l == 0 && r == n ) {
return ans = 0 ;
}
if(l >=1){
time =((double )(wall[r].pos - wall[l].pos))/v ;
ans = min(ans , dp(l,r+1 , 0) + time * c_all[l][r+1]) ;
}
if(r <n ){
time = ((double) (wall[r+1].pos - wall[r].pos))/v ; ;
ans = min(ans , dp(l, r+1, 1) + time * c_all[l][r+1]) ;
}
}
return ans ;
}
}
int sum[1010] ;
int main() {
int x,_v;
double ans ;
int cost ;
while (scanf("%d%d%d" ,&n,&_v,&x)==3 && n + _v + x != 0 ) {
cost = 0 ;
for (int i = 0; i < n ; i++) {
scanf("%d%d%d" ,&wall[i+1].pos,&wall[i+1].c,&wall[i+1].d) ;
cost += wall[i+1].c ;
}
sort(wall+1, wall+n+1) ;
for (int i = 0; i <=n+5; i++) {
for (int j = 0 ; j <= n +5; j++) {
d[i][j][0] = d[i][j][1] = -1 ;
}
}
sum[0] = 0 ;
for (int i = 1; i <= n ; i++) {
sum[i] = sum[i-1] + wall[i].d ;
}
for (int i = 0; i <= n ; i++) {
for (int j = i+1 ; j <=n; j++) {
c_all[i][j] = sum[i] + sum[n] - sum[j-1] ;
}
c_all[i][n+1] = sum[i] ;
}
int s = 1 ;
while (s <= n && wall[s].pos < x) {
s++ ;
}
v = _v ;
if (s == 1) {
ans = dp(1, 2, 0) +(double(wall[1].pos - x) )/v*sum[n] ;
}
else if (s ==n +1 )
{
ans = dp(n, n+1,0) + (double(x- wall[n].pos) )/v*sum[n];
}
else{
ans = min(dp(s-1, s , 0 ) +(double(x- wall[s-1].pos) )/v*sum[n] ,
dp(s-1, s , 1 ) +(double( wall[s].pos-x) )/v*sum[n]);
}
printf("%d\n" ,(int)(ans + 1e-8 +cost)) ;
}
return 0;
}
uva 1336 - Fixing the Great Wall
最新推荐文章于 2020-01-09 18:03:08 发布