bzoj2131 免費的餡餅

2022-05-20 01:28:17 字數 1821 閱讀 4363

第一行是用空格隔開的二個正整數,分別給出了舞台的寬度w(1到10^8之間)和餡餅的個數n(1到10^5)。  接下來n行,每一行給出了一塊餡餅的資訊。由三個正整數組成,分別表示了每個餡餅落到舞台上的時刻t[i](1到10^8秒),掉到舞台上的格仔的編號p[i](1和w之間),以及分值v[i](1到1000之間)。遊戲開始時刻為0。輸入檔案中同一行相鄰兩項之間用乙個空格隔開。輸入資料中可能存在兩個餡餅的t[i]和p[i]都一樣。

乙個數,表示遊戲者獲得的最大總得分。

3 41 2 3

5 2 3

6 3 4

1 1 5

12【資料規模】

對於100%的資料,1<=w,t[i]<=10^8,1<=n<=100000。

這道題真的令我印象十分特別深刻...。 在東北的時候聽過 回來又聽zyl講過

這道題是一道用線段樹解決的二位偏序的$dp$問題

dp[i]表示當前吃第$i$塊餡餅所能夠獲得的最大價值 考慮如何轉移 轉移方程式是很簡單的

$dp[i] = max(dp[j] + val[i])$,$j$屬於能夠轉移到$i$的餡餅

那麼現在需要解決的問題就是哪些餡餅能夠轉移到$i$號 首先$j$號餡餅一定要在$i$號餡餅之前出現

考慮如果$j$

號餡餅能夠轉移到$i$號   

那麼還需要滿足式子

$|pos[i] - pos[j]| <= 2 * (t[i] - t[j])$ 

開啟絕對值之後得到的兩個化簡得到兩個關於$i,j$的式子 將同屬性的移到等式一邊得到

$2 * t[i] - pos[i] >= 2 * t[j] - pos[j]  , 2 * t[i]  + pos[i] >= 2 * t[j] + pos[j]$

發現這兩個式子是等價的 也就是說只要同時滿足上面兩個式子 原始式子就一定成立

證明:$1.pos[i] >= pos[j]$ 也就是說他滿足了式子$1$ 原本$t[i] > t[j]$     那麼$2 * t[i]$加上$pos[i]$後會比左邊更大  一定成立

第二種情況的證明是一樣的 所以兩隻需要同時滿足這兩個屬性就可以進行轉移

**

#include using

namespace

std;

const

int n = 1e5 + 5

;int n,m,tt[n],f[4 *n],w,dp[n];

struct

food b[n];

void

init( )

sort(tt + 1,tt + n + 1

); m = unique(tt + 1,tt + n + 1) - tt - 1;}

void update(int

o)

bool cmp(const food & a,const food &b)

int query(int o,int l,int r,int l,int

r)

void modify(int o,int l,int r,int pos,int

val)

int mid = (l + r) >> 1

;

if(pos <= mid) modify(2 *o,l,mid,pos,val);

else modify(2 * o + 1,mid + 1

,r,pos,val);

update(o);}

intmain( )

printf("%d

",query(1,1,m,1

,m));

return0;

}

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 這樣的話我只會樹套樹 後來想想帶修主席樹應該也行?信仰不夠去 題...