洛谷 P2672 推銷員

2022-05-05 08:09:10 字數 2521 閱讀 7750

阿明是一名推銷員,他奉命到螺絲街推銷他們公司的產品。螺絲街是一條死胡同,出口與入口是同乙個,街道的一側是圍牆,另一側是住戶。螺絲街一共有n家住戶,第i家住戶到入口的距離為si​公尺。由於同一棟房子裡可以有多家住戶,所以可能有多家住戶與入口的距離相等。阿明會從入口進入,依次向螺絲街的x家住戶推銷產品,然後再原路走出去。

阿明每走1公尺就會積累1點疲勞值,向第ii家住戶推銷產品會積累ai​點疲勞值。阿明是工作狂,他想知道,對於不同的x,在不走多餘的路的前提下,他最多可以積累多少點疲勞值。

一、為何不需要動歸

資料範圍在十萬,如果用動歸肯定會爆時空。再說,題目要求輸出多個值,從劃分階段的角度來講就很難劃分。既然是最優化問題,不來一發貪心怎能夠抒發對動歸的憎恨之情呢?

二、怎麼貪

從樣例可得,推銷一家的疲勞值與與兩個因素有關:距離si,積累的疲勞值ai

具體一點,往返2si,推銷ai。所以第一步就可以確定下來了:當x=1時,sum=max(2si+ai);

接下來,si與ai仍然都對ans有關係。分類討論如下:

記走的最遠距離為far

① 如果si② 如果si>far,多走(s[i]-far)*2,即sum+=(s[i]-far)*2;

三、樸素實現

#includeusing

namespace

std;

bool vis[100005

];int a[100005],dis[100005],n,mx,mxdis,far=-1

,tempa,tempb,sum;

int before(int

place)}}

return

bmxdis;

}int after(int

place)}}

return

amxdis;

}int

main()

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

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

}cout

vis[mxdis]=1

; far=mxdis;

sum+=mx;

for(int i=2;i<=n;i++)

else

vis[mxdis]=1

; sum+=mx;

cout

}return0;

}

但是估計你也看到了,這種演算法實在是太慢了,只能得60分(雖然在考場上已經足夠了)。

四、優化

對於dalao來說,可以毫不費力地用上logn資料結構,如線段樹和樹狀陣列。可是我們這種蒟蒻,想都不要想。

可以看到,每次都會選取far左邊和右邊能獲得的最大疲勞值(計算方式不同)。既然是最大,那麼可以使用優先佇列(堆?)優化。

但是優先佇列不支援隨機訪問。如果far改變,就需要重新建立優先佇列。

#include#include

#include

using

namespace

std;

struct

before_house;

struct

after_house;

bool vis[100005

];int a[100005],dis[100005],n,mx,mxdis,far=-1

,tempa,tempb,sum;

priority_queue

before;

priority_queue

after;

bool

operator

<(before_house h1,before_house h2)

bool

operator

<(after_house h1,after_house h2)

//兩種優先佇列的比較方式不同,需要進行過載

void

make_heap()

while(!after.empty())

//清空

before_house bh;

after_house ah;

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

}for(int i=far;i<=n;i++)

}}int

main()

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

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

}cout

vis[mxdis]=1

; far=mxdis;

sum+=mx;

make_heap();

for(int i=2;i<=n;i++)

if(!after.empty())

if(a[tempb]>a[tempa]+(dis[tempa]-far)*2

)

else

sum+=mx;

printf(

"%d\n

",sum);

}return0;

}

最後,祝大家noip2018    rp++

洛谷 P2672 推銷員

阿明是一名推銷員,他奉命到螺絲街推銷他們公司的產品。螺絲街是一條死胡同,出口與入口是同乙個,街道的一側是圍牆,另一側是住戶。螺絲街一共有n家住戶,第i家住戶到入口的距離為si公尺。由於同一棟房子裡可以有多家住戶,所以可能有多家住戶與入口的距離相等。阿明會從入口進入,依次向螺絲街的x家住戶推銷產品,然...

洛谷 P2672 推銷員

題目描述 阿明是一名推銷員,他奉命到螺絲街推銷他們公司的產品。螺絲街是一條死胡同,出口與入口是同乙個,街道的一側是圍牆,另一側是住戶。螺絲街一共有n家住戶,第i家住戶到入口的距離為si公尺。由於同一棟房子裡可以有多家住戶,所以可能有多家住戶與入口的距離相等。阿明會從入口進入,依次向螺絲街的x家住戶推...

洛谷 p2672 推銷員

推銷員 題目鏈結 好了為了湊字數先把題目複製一下 好了題解第一篇正解 首先輸入,莫得什麼好說的 scanf d n for int i 1 i n i scanf d a i s for int i 1 i n i scanf d a i v 然後是思路 對於每乙個x,我們有兩種選擇 選擇前x個a值...