51nod 1380 夾克老爺的逢三抽一

2021-08-15 13:34:09 字數 1803 閱讀 2048

又到了諾德縣的百姓孝敬夾克大老爺的日子,帶著數量不等的銅板的村民準時聚集到了村口。

夾克老爺是一位很」善良」的老爺,為了體現他的仁慈,有一套特別的收錢的技巧。

1、讓所有的村民排成一隊,然後首尾相接排成乙個圈。

2、選擇一位村民收下他的銅錢,然後放過他左右兩邊的村民。

3、讓上述三位村民離開隊伍,並讓左右兩邊的其他村民合攏起來繼續圍成乙個圈。

4、重複執行2、3直到村民全部離開。

夾克老爺的家丁早早的組織村民排成一隊並清點了村民人數和他們手裡的銅錢數量。

作為夾克老爺的首席師爺,你要負責按照夾克老爺的收錢技巧完成納貢的任務。

聰明的你當然知道夾克老爺並不像他表現出來的那樣仁慈,能否收到最多的錢財決定了你是否能夠繼續坐穩首席師爺的位置。

今年村民的人數是n,恰巧是3的倍數。

這題自己想出來了啊,可能是以前做過bzoj2151的緣故吧

在這裡說一下怎麼做

首先,我們要先轉化一下模型

問題等價於n長的陣列中抽取n/

3 n/3

個不相鄰的值使得和最大

我來證明一下:

如果有相鄰的元素,肯定是不合法的方案,因為你選擇乙個,肯定會刪去刪去第二個

那麼就只需要證明如果不相鄰就一定合法就可以了

我們考慮一下,如果我們對於乙個點,如果刪去他不會產生相鄰的元素,那麼我們就先把他刪掉

為什麼這麼刪一定會把元素刪完呢?

因為在若干次後,一定會變成只有一段的,每兩個元素之間只有乙個空格的東西

因為是乙個環,所以可以等價於下面這個

紅色代表選的元素

然後明顯的,最後會有n/2個空格

然後每一次我們刪掉最後乙個紅色就可以了

因為選擇的是n/

3 n/3

個,後面的空格也是n/

3 n/3

個 所以肯定是不會衝突的

於是我們就可以知道通過這種方式刪是合法的了

然後考慮解決上面這個問題,就等價於bzoj2151

這個的過程就是乙個可以後悔的貪心啊

建立乙個大根堆,每一次給予反悔機會就可以了

code:

#include

#include

#include

#include

#include

using namespace std;

typedef long long ll;

const ll n=200005;

ll n,k;

ll a[n];

ll last[n],next[n];

struct qq

;priority_queue q;

bool lalal[n];//這個點還能不能用

void del (ll x)//將這個點刪去

int main()

); }

last[1]=n;next[n]=1;

long long ans=0;

for (ll u=1;u<=n/3;u++)

ans=ans+b.x;

ll a=last[b.id],b=next[b.id];

a[b.id]=a[a]+a[b]-b.x;

del(a);del(b);

q.push(qq);

}printf("%lld\n",ans);

return

0;}

51Nod 1380 夾克老爺的逢三抽一

acm模版 首先發一下官方題解吧 按照官方題解寫的 發現自己一直在第 21 組資料 tl e 很明顯,這組資料是後來加上去專門卡資料的。於是發現自己的 中忽略了乙個部分是暴力的思維,在查詢左右兩側可選的村民時,我用了兩個迴圈,這顯然是不行的,所以我需要使用鍊錶的思維,這樣查詢的複雜度就是 o 1 了...

51nod 1380 夾克老爺的逢三抽一

題目 題解 設最大值為b,左邊為a,右邊為c 解釋一下為什麼要把a c b放回去 因為b不一定是最優的,說不定a c和b差不多大,同時選a c可能比b更優,把a c b放回去,若再次取出,則相當於用兩次選了a和c,滿足題意,也滿足貪心 include using namespace std type...

貪心 51Nod1380 夾克老爺的逢三抽一

這題需要一步轉化,就變成和 bzoj1150 ctsc2007 資料備份backup 一樣了。但不太能直接想到。為什麼題意就等價於選一些不相鄰的點呢?n個點的環,我們選中n 3個點,一定存在乙個選中的點兩側有連續兩個不選的的點,則我們把這個要選的點取掉,不會有兩個要選的點變成相鄰。剩下的就是貪心啦。...