ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила
вернуться в форум

Общий форум

To Christopher Moh or anyone who has solved problem 1143 with DP (+)
Послано Miguel Angel 23 июн 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
Послано Christopher Moh 26 июн 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))