昨天早上上课讲旅行商问题,有点难,这周抽空把3^n的算法码码看。不过这个简化版已经够折腾人了。

其一不看解析不知道这是双进程动态规划,不过我看的解析停留在f[i,j]表示第一个人走到i、第二个人走到j,且1~max(i,j)的都走过的最短路,后面的动态转移方程是我自己写的,不过我的貌似和别人的不太一样?

其二不知道为什么坐标改成real类型就不会207了,这可是个bug?纠结了我一晚上啊昨晚又熬夜了今天早上物理课又打瞌睡了…QAQ

其三给ans或者f数组赋初值不能写maxlongint一定要1e40,因为答案都比maxlongint要大!一开始我还以为是动规出错了怎么一直输出2147xxxxx,哎。

至少表扬下自己想出了动态转移方程吧,话说还有优化空间,因为f[i,j]总是=f[j,i]

program vijos_p1014;
var f,d:array[0..1001,0..1001] of double;
    lx,ly:array[0..1001] of real;
    n,i,j,k:longint;
    ans,t:extended;
function min(x,y:double):double;
begin
  if x<y then exit(x) else exit(y);
end;

function dis(p,q:integer):double;
var t:real;
begin
  t:=(lx[p]-lx[q])*(lx[p]-lx[q])+(ly[p]-ly[q])*(ly[p]-ly[q]);
  exit(sqrt(t));
end;

procedure qsort(l,r:integer);
var i,j:longint;
    midx,midy,t:real;
begin
  i:=l;j:=r;midx:=lx[(l+r) div 2];midy:=ly[(l+r) div 2];
  repeat
    while (lx[i]<midx) or ((lx[i]=midx) and (ly[i]<midy)) do inc(i);
    while (lx[j]>midx) or ((lx[j]=midx) and (ly[j]>midy)) do dec(j);
    if i<=j then
      begin
        t:=lx[i];lx[i]:=lx[j];lx[j]:=t;
        t:=ly[i];ly[i]:=ly[j];ly[j]:=t;
        inc(i);dec(j);
      end;
  until i>j;
  if j>l then qsort(l,j);
  if i<r then qsort(i,r);
end;

begin
  readln(n);
  for i:=1 to n do
    readln(lx[i],ly[i]);
  qsort(1,n);
  for i:=1 to n do
    for j:=1 to n do
      f[i,j]:=1e40;
  f[1,1]:=0;
  for i:=1 to n do
    for j:=1 to n do
      if (i<>j) or ((i=1) and (j=1)) then
      begin
        if i>j then
          begin
            f[i+1,j]:=min(f[i,j]+dis(i,i+1),f[i+1,j]);
            f[i,i+1]:=min(f[i,j]+dis(j,i+1),f[i,i+1]);
          end;
        if i<=j then
          begin
            f[i,j+1]:=min(f[i,j]+dis(j,j+1),f[i,j+1]);
            f[j+1,j]:=min(f[i,j]+dis(i,j+1),f[j+1,j]);
          end;
      end;
  ans:=1e40;
  for i:=1 to n do
    begin
      if f[i,n]+dis(i,n)<ans then ans:=f[n,i]+dis(i,n);
    end;
  writeln(ans:0:2);
end.
旅行商简化版

B.T.W 最近我有一种去哪,哪的OJ就挂的趋势。上周是Codeforces,这周是vijos,难道0 0人品真的差到家了?!

 posted on 2014-03-09 11:50  Sky-Grey  阅读(442)  评论(0编辑  收藏  举报