luogu1484 種樹 神奇的貪心 堆優化

2021-08-18 01:20:14 字數 1252 閱讀 6326

給定一條長度為n的鏈,每乙個點有乙個權值,求不相鄰地選小於等於k個點的總和的最大值

其實這題之前好像在**見過,但是由於當時沒有好好理解,便還是想了一會,當時是乙個環的情況,鏈的情況也差不多。dp其實很容易想,但是時間和空間上都過不去,所以可以考慮貪心,先去選那個權值最大的點,但是這不一定是最優的,我們發現,如果選最大的點不是最優的情況下,那麼只有可能是選這個點限制了旁邊兩個點的選擇,所以旁邊兩個點必須要全部都選,這樣我們可以每次貪心的選取乙個權值最大的點,並把以這個點為中心的三個點全部都縮成乙個新的點,新的點的權值為a[i+1]+a[i-1]-a[i](假設原來的點的編號為i)這樣當我們後面選的點的權值過小的時候,我們就可選擇這個新縮成的點,就相當於不選i號點而選擇了i+1號點和i-1號點,這樣每次地貪心的選取,就相當於每一都會對前面的所有狀態做乙個顛倒,從而找到最後的最優的狀態

就用優先佇列就好了,刪除點的時候不要從優先佇列刪掉,直接標記就好了,注意維護雙向鍊錶和堆中間的值。

/****************====

* author : ylsoi

* algorithm : tanxin

* time : 2018.4.1

* ***************=*/

#include

#include

#include

#include

#include

#include

using

namespace

std;

void file()

#define rep(i,a,b) for(register int i=a;i<=b;++i)

#define drep(i,a,b) for(register int i=a;i>=b;--i)

#define ll long long

#define inf (0x3f3f3f3f)

const

int maxn=5e5+10;

int n,k,l[maxn],r[maxn],head;

ll a[maxn],ans;

bool vis[maxn];

struct node);

while(k--)

else

if(!r[u])

else);

r[l[l[u]]]=u;l[u]=l[l[u]];

l[r[r[u]]]=u;r[u]=r[r[u]];}}

cout

0;}

洛谷1484 種樹

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

洛谷 P1484 種樹

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

國家集訓隊2011 種樹 神貪心

莫名其妙就做了集訓隊的題 不過.資料好水 codevs 1342 哈哈哈亂搞85 貪心的 好像有bug2333 照起點和終點 然後dp搞答案 這個應該很簡單的 要滾一下陣列 同桌打的暴力dp 55好像 思路一樣的 就是省去了那個正確性不一定的貪心 include include define max...