第一行是用空格隔開的二個正整數,分別給出了舞台的寬度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 usingnamespace
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 這樣的話我只會樹套樹 後來想想帶修主席樹應該也行?信仰不夠去 題...