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