ENG  RUSTimus Online Judge
Online Judge
Problems
Authors
Online contests
About Online Judge
Frequently asked questions
Site news
Webboard
Links
Problem set
Submit solution
Judge status
Guide
Register
Update your info
Authors ranklist
Current contest
Scheduled contests
Past contests
Rules
back to board

Common Board

To Christopher Moh or anyone who has solved problem 1143 with DP (+)
Posted by Miguel Angel 23 Jun 2002 08:53
I think that idea is  make DP over a something like a Binary Tree
which is:
function minPath(to_the_right, to_the_left, point):float;
begin
   if to_the_right=to_the_left then
   begin
       mtx[to_the_right,to_the_left]=d(to_the_right,point);
   end
   if not processed(mtx[to_the_right,to_the_left]) then
   begin
   right_branch = d(point, to_the_right) +
    minPath(shift_right(to_the_right),to_the_left, right);
   left_branch = d(point, to_the_left) +
     minPath(to_the_right,shift_left(to_the_left), left);
     mtx[to_th_right,to_the_left]=min(right_branch,left_branch);
   end;
   return mtx[to_the_right,to_the_left];
end;
I mean, the optimal route must not cross itself, so for that
shift_right and shift_left functions. But I get WA, could anyone help
me? Thanks...
mail: miguelangelhdz@hotmail.com

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

#define MaxN 200

struct point { double x, y;};

int    n;
double m[MaxN][MaxN];
point  p[MaxN];

double c(int a, int b)
{
 double xx = (p[a].x-p[b].x)*(p[a].x-p[b].x);
 double yy = (p[a].y-p[b].y)*(p[a].y-p[b].y);
 return sqrt(xx + yy);
}
int next(int i)
{
    if (i+1<n) return i+1;
                 return 0;
}
int prev(int i)
{
    if (i ==0) return n-1;
                  return i-1;
}

double minPath(int r, int l, int dad)
{
    if (r==l)
    {
        if (m[r][l] < 0)
            m[r][l] = c(dad, r);
        return m[r][l];
    }
    if (m[r][l] < 0)
    {
        double right = c(dad, r) +minPath(prev(r), l, r);
        double left  = c(dad, l) +minPath(r, next(l), l);
        if (right < left) m[r][l] = right;
                        else  m[r][l] = left;
    }
    return m[r][l];
}

void main()
{
double min, tot;
int i, j, k;
    cin >>n;
    for (i=0; i<n; i++)
        cin >>p[i].x >>p[i].y;
    min = 0.0;
    for (i=0; i<n-1; i++)
        min = min + c(i, i+1);
    for (j=0; j<n; j++)
        for (k=0; k<n; k++)
            m[j][k] = -1.0;
    for (i=0; i<n; i++)
    {
        tot = minPath(prev(i), next(i), i);
        if (tot < min) min = tot;
    }
    printf("%.3f", min);
}
Re: DP 1143
Posted by Christopher Moh 26 Jun 2002 22:27
My idea is as follows:

Suppose we have computed a partial path a1, a2, a3, ... ai
and we want to add the next point a(i+1) to this path.

There can only be two points that should be considered for the next
point to this path:

The two points adjacent to a1 or ai (one adjacent to a1, the other
adjacent to ai) that have not already been chosen in the path.

Why?  Because choosing any other point would lead at some point to
the path crossing itself, because the polygon is convex (draw a
diagram to convince yourself).

Then the recurrence is as follows:

Let x[a][b] be the weight of the best path starting at vertex a and
ending at vertex b (b can be bigger => counterclockwise path, or a
can be bigger => clockwise path).

Below I assume that b >= a.

x[a][b] = 0 if a == b.

x[a][b] = distance(a,b) if b == a + 1.

x[a][b] = MIN(x[a+1][b]+distance(a,a+1), x[b][a+1]+distance(a,b))