POJ 3817 Robot Challenge (DP)

Robot Challenge
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 603 Accepted: 218

Description

You have entered a robot in a Robot Challenge. A course is set up in a 100m by 100m space. Certain points are identified within the space as targets. They are ordered – there is a target 1, a target 2, etc. Your robot must start at (0,0). From there, it should go to target 1, stop for 1 second, go to target 2, stop for 1 second, and so on. It must finally end up at, and stop for a second on, (100,100).

Each target except (0,0) and (100,100) has a time penalty for missing it. So, if your robot went straight from target 1 to target 3, skipping target 2, it would incur target 2?s penalty. Note that once it hits target 3, it cannot go back to target 2. It must hit the targets in order. Since your robot must stop for 1 second on each target point, it is not in danger of hitting a target accidentally too soon. For example, if target point 3 lies directly between target points 1 and 2, your robot can go straight from 1 to 2, right over 3, without stopping. Since it didn't stop, the judges will not mistakenly think that it hit target 3 too soon, so they won't assess target 2's penalty. Your final score is the amount of time (in seconds) your robot takes to reach (100,100), completing the course, plus all penalties. Smaller scores are better.

Your robot is very maneuverable, but a bit slow. It moves at 1 m/s, but can turn very quickly. During the 1 second it stops on a target point, it can easily turn to face the next target point. Thus, it can always move in a straight line between target points.

Because your robot is a bit slow, it might be advantageous to skip some targets, and incur their penalty, rather than actually maneuvering to them. Given a description of a course, determine your robot's best (lowest) possible score.

Input

There will be several test cases. Each test case will begin with a line with one integer, N (1 ≤ N ≤ 1000) which is the number of targets on the course. Each of the next N lines will describe a target with three integers, X, Y and P, where (X,Y) is a location on the course (1 ≤ X,Y ≤ 99, X and Y in meters) and P is the penalty incurred if the robot misses that target (1 ≤ P ≤ 100). The targets will be given in order – the first line after N is target 1, the next is target 2, and so on. All the targets on a given course will be unique – there will be at most one target point at any location on the course. End of input will be marked by a line with a single 0.

Output

For each test case, output a single decimal number, indicating the smallest possible score for that course. Output this number rounded (NOT truncated) to three decimal places. Print each answer on its own line, and do not print any blank lines between answers.

Sample Input

1
50 50 20
3
30 30 90
60 60 80
10 90 100
3
30 30 90
60 60 80
10 90 10
0

Sample Output

143.421
237.716
154.421

Source

2009 ACM ICPC Southeast USA Regional Programming Contest


/*************************************************************************
	> File Name: BB.cpp
	> Author: BSlin
	> Mail:  
	> Created Time: 2013年10月24日 星期四 15时54分03秒
 ************************************************************************/

#include <stdio.h>
#include <string.h>
#include <math.h>

struct point {
    double x,y,value;
}P[1010];

double dp[1010];

double dis(point A, point B) {
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

double min(double a, double b) {
    return a>b ? b : a;
}

int main() {
    freopen("in.txt","r",stdin);
    int n;
    double temp;
    while(scanf("%d",&n)) {
        memset(dp,0,sizeof(dp));
        if(n == 0) 
            break;
        P[0].x = 0;
        P[0].y = 0;
        P[0].value = 0;
        for(int i=1; i<=n; i++) {
            scanf("%lf%lf%lf",&P[i].x,&P[i].y,&P[i].value);
            P[i].value = P[i-1].value + P[i].value;
        }
        P[n+1].x = 100;
        P[n+1].y = 100;
        P[n+1].value = P[n].value + 1;
        dp[0] = 0.0;
        for(int i=1; i<=n+1; i++) {
            temp = 150000.0;
            for(int j=0; j<i; j++) {
                temp = min(temp,dp[j] + dis(P[i],P[j]) + (P[i-1].value - P[j].value));
            }
            dp[i] = temp + 1;
        }
        printf("%.3f\n",dp[n+1]);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值