51nod 1331 狹窄的通道

2022-04-30 13:00:13 字數 3127 閱讀 1033

有乙個長為l的狹窄通道,我們假設這個通道在x軸上,其兩個出口分別在x=0與x=l處。在這個通道裡有n只狼,第i只狼有乙個初始位置ai,它想到達位置bi(0<=i=l處空間足夠大可以裝下任意數量的狼。那麼所有的狼想從ai到bi它們總共最少走多遠的距離,輸出這個距離。

注意:在x<=0和x>=l的通道外部空間中移動的距離不計算在內;另外,x=0到x=l只能通過通道連通,即通道外面的世界不能從x=0走到x=l處。

多組測試資料,第一行乙個整數t,表示測試資料個數,其中1<=t<=15. 之後有t組相同結構的測試資料: 每組資料第一行兩個整數n,l,其中1<=n<=50,2<=l<=1,000,000(即10^6) 之後n行,每行兩個整數ai與bi,其中1<=ai,bi<=l-1,且保證所有的狼的起點ai各不相同且終點bi也各不相同。

每組測試資料一行輸出,即所有狼在通道中運動的最小距離。

2 2 5

1 3

2 4

2 10

3 8

9 64

14知道這道題是因為無。比。良。心。的srm-03=v=

ac的人數太少……網上根本找不到什麼正經的題解,於是只能靠自己瞎yy

然後,來寫一篇正(luan)經(gao)的題解好了✔

先把所有的狼按起點從小到大sort一發,編號分別為1~n,這是一切的開始(霧。

首先,依據題意,所有的狼可以全往左走或是全往右走而不會造成衝突(顯然。

然後,我們可以把所有的狼按起點分為左中右三部分,這三部分中狼的數量可以為0。且中間部分的狼,本身不互相衝突且不與左右衝突,即它們可以直接從起點走到終點。這時候,有一種解決方案為:左邊的狼先全部移向0,再移向各自終點;中間的狼直接從各自起點移向終點;右邊的狼先全部移向l,再移向各自終點。比如樣例,還有類似下面這種:(圖醜將就qwq

**還是很好碼的……思路就是先列舉左邊部分的狼,再計算中間部分的狼(貪心 ,顯然中間部分的狼越多越好;所以我們只需要順序列舉下去,直到出現衝突為止),然後計算總代價並更新答案。

另,判斷方案可行的方法是,左邊最右的終點在右邊最左的終點的左邊(看起來很繞???手動畫一下圖吧w

你以為這樣就結束了嗎

樣例過了?興奮地交了?

什麼?只過了七個點?

再來看一組資料咯(llq大佬找出來的,orz

1        

5 11        

5 3     

3 4     

1 10     

7 9     

9 1這組資料,正確答案是48。

過程如下:先將編號為1、2、3的狼移向0,編號為4、5的狼移向l,總代價為15;再將編號為1的狼移向l,將編號為5的狼移向0,總代價累計37;最後將所有的狼移向各自終點,答案為48。顯然不滿足我們之前的思路,因為狼會兩邊跑(驚不驚喜 意不意外 開不開心=v=

如果說,我們之前討論的是情況1,那麼我們現在需要討論情況2。

情況2可以用網路流寫,具體右拐@yy大佬

現在我們來講列舉+貪心。(為了想這東西期末統考掛科了,很氣

流程大概是:按起點列舉劃分,左邊的移向0,右邊的移向l → 解決終點的衝突問題。簡單地說就是,先按起點劃,左往左右往右;再按終點劃,左邊的終點全在右邊的終點的左邊,即不會造成衝突。

(在寫完之後看了一下蔥神的**,發現其實是可以直接列舉分割點的,**會簡潔很多。

好吧還是打算解釋一下自己的思路,畢竟srm-04資料範圍變大後實測跑得飛快。

1 #include2 #include3 #include4 #include5

using

namespace

std;

6long

long

ans,sum,summ;

7int

t,n,l;

8struct nodea[105];9

intread()

1013

while(c>='

0'&&c<='9')

14return x*f;15}

16bool cmp1(node a,node b)

17bool cmp2(node a,node b)

18bool okey(int l1,int r1,int l2,int

r2)19

25void

cond1()

2635 summ+=abs(a[j].s-a[j].t);36}

37 sum+=summ;

38for(int j=cut;j<=n;j++)sum+=2*l-a[j].s-a[j].t;

39 ans=min(ans,sum);40}

41}42void solc(int

x)43

60 ans=min(ans,sum+sum1);61}

62void

cond2()

6374}75

void

solve()

7685

intmain()

86

view code

起點列舉劃分這個……直接列舉計算就好了,主要問題在解決衝突。

我直接拿上面那個例子的正確過程來解釋吧。

將編號為1、2、3的狼移向0,編號為4、5的狼移向l之後,呈現出如上圖情況。顯然,他們在跑向各自終點的過程中會出現衝突,所以需要調整。

以下是對solc函式的解釋:起點分割點(即x)左右,分別按終點順序sort。li為左邊第一只狼,ri為右邊第一只狼。順序列舉,直到li與ri發生衝突:在圖中,li為1,ri為3。然後對ri進行調整,即把所有與li衝突的ri打包起來算,提高效率。為了解決衝突:1、把所有li右移,計算代價sum2,此時解決了所有衝突,可以直接更新答案;2、把衝突的ri左移,因為此時只解決了一部分衝突,所以我們需要以計算好的sum+sum1進入下一輪計算,直到所有的衝突都被解決才在最後更新答案。

大概就這樣咯。祝玩的愉快

51 nod 最高的獎勵

有n個任務,每個任務有乙個最晚結束時間以及乙個對應的獎勵。在結束時間之前完成該任務,就可以獲得對應的獎勵。完成每乙個任務所需的時間都是1個單位時間。有時候完成所有任務是不可能的,因為時間上可能會有衝突,這需要你來取捨。求能夠獲得的最高獎勵。input 第1行 乙個數n,表示任務的數量 2 n 500...

51Nod 1241 特殊的排序

題目傳送門 分析 之前想的是求lis,後面發現這組資料會出問題 3 1 2 4 5 6。其實這裡的lis還應當滿足前後兩個元素的值相差為1。比如上面的最長子串行為 3 4 5 6,而不是1 2 4 5 6。即只需移動1 2即可。即如果n個數最長連續上公升子串行 這裡的連續指數值上連續,即前後相差1 ...

51nod 1091 線段的重疊

基準時間限制 1 秒 空間限制 131072 kb 分值 5 難度 1級演算法題 x軸上有n條線段,每條線段包括1個起點和終點。線段的重疊是這樣來算的,10 20 和 12 25 的重疊部分為 12 20 給出n條線段的起點和終點,從中選出2條線段,這兩條線段的重疊部分是最長的。輸出這個最長的距離。...