BZOJ3387 跨欄訓練

2022-06-12 12:51:08 字數 1422 閱讀 8652

為了讓奶牛參與運動,約翰建造了 $k$ 個柵欄。每條柵欄可以看做是二維平面上的一條線段,它們都平行於 x 軸。第 $i$ 條柵欄所覆蓋的 x 軸座標的區間為$[a_i,b_i]$,y 軸高度就是 $i$。一開始,奶牛在座標 $(s,k+1)$處,它們的家在原點處,所以要想要回家就必須「跨」一些柵欄。

但奶牛們是跨不過柵欄的,它們只能繞過柵欄。在二維平面上,它們只能沿水平和垂直方向移動,如果前進的道路上出現柵欄,它們就不能前進,必須沿水平方向移動到沒有柵欄的地方再前進。奶牛們希望走的路越短越好,由於在垂直方向上的路程是確定的,你只需要幫它們求出在水平方向的最短路程就可以了。

並且從出發點走到原點的路程一定與從原點走到出發點的路程相同

設$dp_$為從原點走到第$i$條線段的左/右端點需要走的最小距離,$j_1,j_2$分別為$i$線段左右端點正下方第一條線段的編號,轉移需要從該線段來

$$dp_=min(dp_+|a_j-a_i|,dp_+|b_j-a_i|)$$

$$dp_=min(dp_+|a_j-b_i|,dp_+|b_j-b_i|)$$

將出發點視為一條$0$長線段

#include#include

#include

using

namespace

std;

int k,s,a[100005],b[100005

];long

long dp[100005][2

];struct

segtree[

800050

];inline

intread()

while(ch>='

0'&&ch<='9'

)

return f*w;

}void pushdown(int i,int l,intr)}

int query(int i,int l,int r,int

p) pushdown(i,l,r);

int mid=l+r>>1

;

if(p<=mid)

return query(i<<1|1,mid+1

,r,p);

}void update(int i,int l,int r,int l,int r,intv);

return

; }

pushdown(i,l,r);

int mid=l+r>>1

;

if(l<=mid)

if(r>mid)

}int

main()

a[k+1]=b[k+1]=s;

for(int i=1;i<=k+1;i++)

}printf(

"%lld\n

",dp[k+1][0

]);

return0;

}

跨欄訓練

338 位元位計數

給定乙個非負整數num。對於0 i num範圍中的每個數字i,計算其二進位制數中的 1 的數目並將它們作為陣列返回。示例 1 輸入 2輸出 0,1,1 示例 2 輸入 5輸出 0,1,1,2,1,2 高階 要求演算法的空間複雜度為o n 你能進一步完善解法嗎?要求在c 或任何其他語言中不使用任何內建...

338 位元位計數

給定乙個非負整數num。對於0 i num範圍中的每個數字i,計算其二進位制數中的 1 的數目並將它們作為陣列返回。示例 1 輸入 2 輸出 0,1,1 示例 2 輸入 5輸出 0,1,1,2,1,2 高階 要求演算法的空間複雜度為o n 你能進一步完善解法嗎?要求在c 或任何其他語言中不使用任何內...

338 位元位計數

題目描述 給定乙個非負整數 num。對於 0 i num 範圍中的每個數字 i 計算其二進位制數中的 1 的數目並將它們作為陣列返回。示例 1 輸入 2 輸出 0,1,1 示例 2 輸入 5 輸出 0,1,1,2,1,2 高階 方法1 直接對每乙個數字進行判斷 主要思路 1 對每乙個數字單獨判斷其二...