推銷員(優先佇列 貪心)

2021-07-22 03:32:57 字數 1312 閱讀 8857

2015 noip 普及組

題目描述:

阿明是一名推銷員,他奉命到螺絲街推銷他們公司的產品。螺絲街是一條死胡同,出口與入口是同乙個,街道的一側是圍牆,另一側是住戶。螺絲街一共有n家住戶,第i家住戶到入口的距離為si公尺。由於同一棟房子裡可以有多家住戶,所以可能有多家住戶與入口的距離相等。阿明會從入口進入,依次向螺絲街的x家住戶推銷產品,然後再原路走出去。阿明每走1公尺就會積累1點疲勞值,向第i家住戶推銷產品會積累ai點疲勞值。阿明是工作狂,他想知道,對於不同的x,在不走多餘的路的前提下,他最多可以積累多少點疲勞值。

輸入描述:

第一行有乙個正整數n,表示螺絲街住戶的數量。

接下來的一行有n個正整數,其中第i個整數si表示第i家住戶到入口的距離。資料保證s1≤s2≤…≤sn<10^8。

接下來的一行有n個正整數,其中第i個整數ai表示向第i戶住戶推銷產品會積累的疲勞值。資料保證ai<10^3。

輸出描述 output description

輸出n行,每行乙個正整數,第i行整數表示當x=i時,阿明最多積累的疲勞值。

樣例輸入:

1≤n≤100000

思路:

s表示到出口的路程,v表示疲勞值

優先佇列,過載運算子使結構體在佇列中按照疲勞值由大到小排列。

貪心思想:x=i時找的人一定是x=i-1時找的人再加上乙個。

當x=1時,一定是找v+s*2最大的那乙個。用now表示現在在哪乙個房屋。

從now到n列舉找出最優的那乙個,把now到next的房屋加入佇列。彈出隊手,加入答案,再讓now=next,繼續尋找以後的最優值。

#include

#include

using

namespace

std;

const

int maxn=100010;

struct node

e[next].v+=(e[next].s-e[now].s)*2;//更新

if(now!=next)

q.push(e[next]);//入隊

for(int j=now+1;j//now到next之間的房屋入隊

q.push(e[j]);

s=q.top();//彈出隊位

ans+=s.v;//加入答案

q.pop();

cout

now=next;//now=next繼續尋找最優值

}return

0;}

20160802 推銷員 貪心 堆

這題最重要的結論就是x i時的選擇必定包含x i 1時的所有點。這樣我們記錄當前選擇的最遠距離,在其左右分別維護乙個堆,左邊的不算距離,右邊的算距離 要減去當前最遠距離 每次從兩堆頂中選擇最優解,如果更新了最遠距離,就要將右邊堆中這個距離左邊的點都拿出來減去距離扔到左堆裡。重複n次即可。這個時候再次...

luogu P2672 推銷員 貪心

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

普及 NOIP 2015 推銷員 貪心

noip 2015 推銷員 題意 思路 貪心,首先按每戶人家的推銷疲勞度從大到小排序,考慮選定一組,走路帶來的疲勞度是定的,就是最遠那個 2.所以對於每個答案 max sum i mx 2 sum i 1 h i 其中sum是排序後對推銷疲勞度做的字首和,而h i 儲存 從 i 到 n中,最大的 2...