zoukankan      html  css  js  c++  java
  • [vijos P1014] 旅行商简化版

    昨天早上上课讲旅行商问题,有点难,这周抽空把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人品真的差到家了?!

  • 相关阅读:
    shell 学习笔记 LinuxShell脚本攻略(第2版)
    [六省联考2017]分手是祝愿
    [SDOI2010]粟粟的书架
    [CQOI2018]解锁屏幕
    [SCOI2007]最大土地面积
    CF369E Valera and Queries
    CF817F MEX Queries
    [HEOI2016/TJOI2016]求和
    [CQOI2018]九连环
    [HNOI2015]亚瑟王
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3589781.html
Copyright © 2011-2022 走看看