2008GDSOI 魚肉炸彈(樹形dp)

2021-10-09 06:11:29 字數 3464 閱讀 5342

description

舒克和貝塔終於下定決心要去營救被關押在眾貓聚居的a城中的大公尺同志。

a城的構造是很奇怪的。a城中的所有n棟建築沿著一條直線排列,而且沒有兩棟樓的高度是相同的。而大公尺同志就被關押在其中的某棟建築中。每一棟建築的頂上都是有一些貓們在看守的。如果按照從一端到另一端的順序將所有的建築編號為1到n,那麼第i棟建築的高度為hi,頂上的貓的數量為ci.

每乙隻貓不但可以看守住其所在建築的樓頂,還可以看守住一些比它所在建築要低的樓的樓頂。前提是沒有被其他樓所擋住。a城中的建築都是很高的,高到可以忽略它們之間的距離和它們的水平面面積。於是可以認為,樓i上的貓能看守樓j的樓頂,當且僅當樓i的高度不低於樓j,且樓i到樓j之間的所有樓房的高度都低於樓i。

現在,神勇的貝塔同學已經潛入了a城內部營救大公尺同志,而舒克則負責駕駛***提供空中支援。按照約定,貝塔找到並救出大公尺後會爬上樓頂施放訊號讓舒克前來接應。

舒克的飛機上裝備有k枚魚肉炸彈。每一枚魚肉炸彈都可以在被投放到某一座樓的樓頂一段時間之後使該樓所有貓喪失行動能力。由於舒克並不知道貝塔會登上哪座樓的樓頂,所以現在他決定減少在最壞情況下與貝塔匯合時被發現的可能。具體來說,假設第i棟樓被si只貓看守(注意si只貓包括該樓上的ci只貓以及其他樓上所有能看守該樓頂的貓),他希望使用這k枚炸彈使得si中的最大值最小。聰明的舒克很快就通過正確地選擇炸彈投放地點完成了一這目標。你能嗎?

input

第一行有兩個整數n和k。

第二行至第n+1行每行有兩個整數,依次為編號為1的樓到編號為n的樓的高度(hi)和樓頂的貓數(ci)。

資料規模:

1<=n<=100000

1<=k<=5

1<=hi<=1000000000

0<=ci<=1000000000

output

在這個題目中,你只需輸出乙個整數,表示使用k枚炸彈所能達到的si中的最大值最小能是多少。

sample input

樣例1

321

2312

2

樣例2

311

2312

2

樣例3

511

4513

4422

5

sample output

樣例1

1

(說明:可投放在第一座樓和第三座樓上)

樣例2

2

(說明:可投放在第二座樓上)

樣例3

6

(說明:可投放在第四座樓上)

思路:

看到題目,可能大家覺得這根本就不是乙個動態規劃(樹形dp),沒關係,一起來慢慢推吧!

首先我們要知道s[i],表示能監視樓i的所有cat,不一定是這棟樓上的。

接著,對於n棟樓中,哪一棟能對n棟樓上的s[i]都有貢獻呢?俗話說的好:站的高,看得遠。沒錯,n棟中最高的樓一定對每棟樓都有貢獻的。那大家是不是猜到了,我們把就把最高樓作為根,它左邊為左子樹,右邊為右子樹;

如樣例一:32

1231

222(3,

1) / \ 1(

1,2)

2(2,

2)//注:以前我從來不建樹,要不是沒要辦法,這題也不想。(碼風清奇,勿噴!!!)

ll build

(ll l,ll r)

既然我們都推出如何建樹了,那麼再來證明一下為什麼是樹形dp吧!

假如一棵樹要放k枚炸彈,是不是可以分為左邊炸i個,右邊炸k-i個;當然我們也可以左邊炸i個,右邊炸k-i-1個(為什麼要減一,後面講)。管他有幾種不同的,是不是就是乙個父子節點依賴子節點的關係,這不就是個樹形dp了嗎?

動態轉移方程

根據上面說的,大家可能已經想到了……

設f[root][k]表示以root為根的子樹,放k枚炸彈的最小最大值。

那我們是不是可以分為兩種情況來討論:

1.左子樹放i枚炸彈,右子樹放j枚炸彈,根不放 i+j<=k

2.左子樹放i枚炸彈,右子樹放j枚炸彈,根放一枚炸彈 i+j+1<=k

那方程不就歐了。

f[root]

[i+j]

=min

(f[root]

[i+j]

,max

(f[e[root]

.l][i]

,f[e[root]

.r][j]

)+c[root]);

//情況一

if(i+j+

1<=k)

f[root]

[i+j+1]

=min

(f[root]

[i+j+1]

,max

(f[e[root]

.l][i]

,f[e[root]

.r][j]))

;//情況二

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);

using

namespace std;

const

int max=

2147483647

;const

int n=

1e5+10;

struct node

e[n]

;ll n,k,h[n]

,c[n]

,id,f[n][5

];bool vis[n]

;ll build

(ll l,ll r)

void

tree_dp

(ll root)

}int

main()

id=build(1

,n);

tree_dp

(id)

;printf

("%lld"

,f[id]

[k])

;return0;

}

2008汶川加油!2008中國加油!!

2008年5月12號下午2點28分,四川省汶川縣發生7.8級特大 突如其來的 在瞬間震碎無數家庭的幸福,乙個個鮮活的生命,剎那間被廢墟所掩埋。四川汶川也成為所有中國人心中之痛!一方有難,八方支援,發生以後,全國火速開始了緊張的救援工作,人民子弟兵火速開往災區第一線,緊急開展救援工作,各地人民紛紛獻愛...

VS2008 ,TFS2008破解序列號

將試用版 90天 變成永久正式版的方法 一 先安裝試用版,然後在 新增或刪除程式 裡找到vs2008,點 更改 刪除 就會看到乙個輸入序列號的地方,把序列號輸進去,點 公升級 按鈕即可,team suite和professional通用。以下是收集的序列號 1.visual studio 2008 ...

選號精靈2008

功能介紹 1 可以完成單號 多號 單級和多級的 選號任務 2 開始後號碼在螢幕上閃動,按空格鍵後停止鎖定號碼,進行公示或確認。再次按空格健繼續下一輪的選號 3 按ctrl q軟體結束執行 4 可以設定參與閃動的資料項 5 可以設定最少閃動時間和最少公示時間,到時後按空格才有效 6 可以設定是否顯示時...