洛谷 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有某種神能力,能預知自己在某個坑種樹的獲利會是多少 可能為負 請你幫助他計算出他的...