XYLX 10.19 天堂(HEAVEN)

XYLX 10.19 天堂(HEAVEN)


題目描述

每一個要上天堂的人都要經歷一番考驗,當然包括小X,小X開始了他進入天堂的奇異之旅。地獄有18層,天堂竟然和地獄一樣,也有很多很多層,天堂共有N層。從下到上依次是第1,2,3,…,N層,天堂的每一層都是一個延伸無限遠的地板,在地板上人可以任意走動,層與層之間是平行關係,每一層的地板都是由人不能穿過的物質構成,幸好每一層地板上有且僅有1個人可以通過的洞口。
我們可以把小X和洞口,還有下面提到的氣球店都看成點,座標是二維的。小X開始在第1層的(0,0).

小X的重量爲M,第i層與第i+1層之間的特殊氣體能浮起的重量爲Wi ,每一層的地面上散落了若干個氣球店,多個氣球店可以在同一點,每個氣球可以浮起的重量是1,去一個氣球店一次只能領取一個氣球,不能連續在一個氣球店領取氣球,當然你可以在兩個氣球店之間來回跑,每個氣球店供應的氣球都是無限多的。第i層的氣球只能在第i層進入第i+1層時使用,當小X在第i層,只有站到了第i+1層洞口的位置(在其它位置不會浮起),並且自身的重量小於等於氣球和特殊氣體浮起重量的總和,纔可以進入第i+1層。小X想知道他要到達第N層走過的長度最少是多少?題目保證有解。


輸入輸出


輸入文件

第1行: 三個正整數N,M,Q(Q表示氣球店)
第2行: 共2*(N-1)個整數,每兩個數描述1個洞口座標,第i對xi,yi表示第i+1層的洞口位置(xi,yi)。
第3行: 共N-1個整數,第i個數爲Wi。
往後Q行,每行三個整數x,y,z , 表示第Z層有一個氣球店,座標爲(x,y)


輸出文件

1個實數L,保留兩位小數,表示小X最少要走的長度。


樣例


樣例輸入

3 10 4
0 0 1 2
9 0
0 1 1
2 3 1
0 1 2
1 1 2

樣例輸出

13.00


註釋


【樣例解釋】

在第一層從(0,0)出發到(0,1)取得1個氣球並返回(0,0)即可到達第二層。長度:2.00
在第二層,從(0,0)到(0,1)領取氣球,再到(1,1)領取氣球,兩個點來回跑,第5次到達(1,1)時恰好氣球數達到10,走到(1,2)即可到達第3層終點。長度:11.00
總長度:13.00


【數據範圍】

2<=N<=100
每層的氣球店數目不超過50。
0<=M<=100, 0<=Wi<=100
座標-3000<=x,y<=3000


分析

從網上看題解後自己的總結
首先要到最高層,每層都是互不影響的,所以分層動歸,當每層都是最小的時候肯定所有也是最小,因此我們對該題分層動歸,當特殊氣球即可滿足需求時代價就爲從一點到另一點的距離;
方程

f[i,j]:=min(f[i,j],f[i-1,p]+從p氣球店到j氣球店的距離)(p<>j,p∈該層所有氣球店)
f[1,j]:=(從起點到j氣球店的距離)

代碼如下

program heaven;
type rec=record
      x,y:longint;
     end;
var i,j,k,p,n,m,q,w,x,y,z:longint;
    ans,minn:double;
    sum:array[1..100] of integer;
    balloon:array[1..100,1..50] of rec;
    need:array[1..100] of longint;
    elevator:array[1..100] of rec;
    f:array[0..100,1..100] of double;
function min(a,b:double):double;
begin
 if a<b then exit(a);
 exit(b);
end;

begin
 readln(n,m,q);
 for i:=1 to n-1 do
  begin
   read(elevator[i].x,elevator[i].y);
  end;
 for i:=1 to n-1 do
  begin
   read(w);
   need[i]:=m-w;
  end;
 for i:=1 to q do
  begin
   readln(x,y,z);
   inc(sum[z]);
   balloon[z,sum[z]].x:=x;
   balloon[z,sum[z]].y:=y;
  end;
 x:=0;
 y:=0;
 for i:=1 to n-1 do
  begin
   if need[i]<=0
    then
     begin
      ans:=ans+sqrt(sqr(elevator[i].x-x)+sqr(elevator[i].y-y));
      x:=elevator[i].x;
      y:=elevator[i].y;
     end
    else
     begin
      for j:=1 to sum[i] do
       f[1,j]:=sqrt(sqr(balloon[i,j].x-x)+sqr(balloon[i,j].y-y));
      for k:=2 to need[i] do
       begin
        for j:=1 to sum[i] do
         begin
          f[k,j]:=maxlongint;
          for p:=1 to sum[i] do
           begin
            if j<>p
             then
              f[k,j]:=min(f[k,j],f[k-1,p]+sqrt(sqr(balloon[i,j].x-balloon[i,p].x)+sqr(balloon[i,j].y-balloon[i,p].y)));
           end;
         end;
       end;
      minn:=maxlongint;
      for j:=1 to sum[i] do
       begin
        minn:=min(minn,f[need[i],j]+sqrt(sqr(balloon[i,j].x-elevator[i].x)+sqr(balloon[i,j].y-elevator[i].y)));
       end;
      ans:=ans+minn;
      x:=elevator[i].x;
      y:=elevator[i].y;
     end;
  end;
 write(ans:0:2);
end.

套用

仍然空洞的明日 是最接近黑的灰
無法成爲任何東西 是最接近黑的灰

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章