洛谷 P1484 種樹 思維 堆

2021-10-01 23:43:43 字數 1335 閱讀 7480

洛谷 p1484 種樹 思維+堆

很容易想到用乙個大根堆來儲存每個位置的獲利,但我們不能每次都取出根元素後,將其兩邊的元素標記位不可選擇,因為這個根元素兩邊的元素之和很可能大於這個根元素,這時我們選擇的就不是根元素,而是兩邊的元素,所以我們要有乙個反悔選擇的機會,我們在選擇根元素的時候,在總獲利中加上其獲利,並把這個根元素的獲利變為兩邊元素的獲利之和減去根元素的獲利,並將這個根元素重新放入大根堆,這樣我們就有了反悔的機會,同時需要刪除兩邊的元素,因為它們已經用不到了。

#include

#include

#include

#define max 500005

using namespace std;

int n,k,flag[max]

=,num[max]

;//num記錄在某個地方的獲利

long

long tot=0;

//總獲利

int l[max]

,r[max]

;struct node

bool operator <

(const node &a)

const};

priority_queue q;

intmain()

l[0]

=1,r[n+1]

=n;for

(int i=

0;i) node t=q.

top();

q.pop();

if(t.key<=0)

tot+

=t.key;

//總獲利增加t.key

int id=t.loc;

num[id]

=num[l[id]

]+num[r[id]

]-num[id]

; t.key=num[id]

; flag[l[id]

]=flag[r[id]]=

1;//標記左右坑不可選擇

l[id]

=l[l[id]];

//id的左坑變為它左坑的左坑

r[id]

=r[r[id]];

//id的右坑變為它右坑的右坑

l[r[id]

]=id;

//id右坑的左坑變為id

r[l[id]

]=id;

//id左坑的右坑變為id

q.push

(t);

}printf

("%lld"

,tot)

;return0;

}

洛谷 P1484 種樹

本題說每選乙個坑,它的左右兩個坑都不能選了,可是我們沒有辦法確定我們選某個坑一定是最優解,怎麼辦呢?我們設定乙個反悔機制,每當選乙個坑,就新設定乙個點,使這個點的值為這個坑兩邊的和減去當前坑的差.為什麼這樣做是對的呢?感性想一下,如果再後面的選坑過程中,我們選到了這個新設定的點,說明我們選上文的那個...

洛谷P1484種樹(堆 較難貪心)

題意很清晰很好懂,做起來就難了。資料範圍小的化可搜尋可dp,but資料這麼大是不可能的了,較難貪心 a i 或左加右只選乙個最大的 堆 每次取出最大的 1 include 2 include 3 include 4 using namespace std 5 typedef long long ll...

後悔貪心法 種樹(洛谷 P1484)

題目描述 cyrcyr今天在種樹,他在一條直線上挖了n個坑。這n個坑都可以種樹,但為了保證每一棵樹都有充足的養料,cyrcyr不會在相鄰的兩個坑中種樹。而且由於cyrcyr的樹種不夠,他至多會種k棵樹。假設cyrcyr有某種神能力,能預知自己在某個坑種樹的獲利會是多少 可能為負 請你幫助他計算出他的...