BZOJ 2131 免費的餡餅 DP 樹狀陣列

2021-08-10 04:38:19 字數 1578 閱讀 4514

這題好神啊!首先要會最簡單的dp:先按t從小到大排序,f[

i]表示接到排序後第i塊餡餅的最大分數和,那麼轉移就是把前面的掃一遍,複雜度o(

n2) 。我們觀察轉移的條件,若能從f[

j]轉移到f[

i],那麼有:t[

j]<=t[

i] p

[i]−

p[j]

<=2×

(t[i

]−t[

j])

p[j]

−p[i

]<=2×

(t[i

]−t[

j])

(後面兩條不等式實際上是由|p

[i]−

p[j]

|<=2×

(t[i

]−t[

j]) 得到的)

我們又注意到,滿足第2、3條不等式,那麼第1條就一定滿足。那麼對於第2、3條,移項可得:2×

t[i]

+p[i

]>=2×

t[j]

+p[j

] 2×

t[i]

−p[i

]>=2×

t[j]

−p[j

] 設x

[i]=

2×t[

i]+p

[i],

y[i]

=2×t

[i]−

p[i]

,f[j

] 能轉移到f[

i]的條件就是x[

j]<=x[

i] 且y

[j]<=y[

i],你也可以這麼理解,平面上在i左下角的點都可以轉移到i。然後就好搞了,對x排序,然後離散化y,用樹狀陣列維護最大值,就可以做到o(

nlog

n)轉移了。

#include

using

namespace

std;

#define pa pair

#define ll long long

const

int maxn=100010;

const

int inf=2147483647;

int read()

while(ch>='0'&&ch<='9')

return x*f;

}int w,n,f[maxn],y[maxn],ans=-1;

struct aa[maxn];

bool cmpxy(a a,a b)

int getmax(int x)

mapo;

int main()

sort(a+1,a+1+n,cmpxy);

sort(y+1,y+1+n);int num=0;

for(int i=1;i<=n;i++)

for(int i=1;i<=n;i++)

printf("%d",ans);

}

bzoj2131 免費的餡餅

智障一般的操作,拆絕對值都忘了。數學沒救了。最後貌似是用的幾何意義推出來的。轉移的條件是 t i t j 並且abs p i p j 2 t i t j 顯然前面那個可以不考慮。然後你把每個狀態看作乙個二維平面上的點nd i 2 t i p i 移向不難發現 nd i 能夠轉移的點就是y x,y x...

bzoj 2131 免費的餡餅

易得方程 f i max f j v i 條件是 t i 一共有 3 個條件,但是你發現如果滿足後面兩個條件,自然滿足第乙個條件.所以可以將問題轉化為乙個二位偏序問題,離線 樹狀陣列處理一下即可.code include define n 100007 define ll long long usi...

bzoj2131 免費的餡餅

首先我們很容易看出是乙個dp 然後容易看出是資料結構優化dp 但是這個限制條件有點鬼畜 abs p i p j 2 t i t j p i p j t i 2 p i t j 2 p j p i t i 2 p i t j 2 p j 這樣的話我只會樹套樹 後來想想帶修主席樹應該也行?信仰不夠去 題...