[bzoj2131]免費的餡餅_樹狀數組
阿新 • • 發佈:2018-07-25
-s size ask bit mil 最大 hash unique ret
免費的餡餅 bzoj-2131
題目大意:
註釋:$1\le n \le 10^5$,$1\le w \le 10^8$。
想法:首先,想到dp
狀態:dp[i][j]表示i分鐘在位置j的最大收益
優化優化
狀態:dp[i]表示最後收到i的最大收益。
轉移:順序枚舉i:1->n即可。
然後,我們嘗試優化
對於這個狀態我們會發現轉移的時候有一個絕對值的死東西,我們將它拆開就有:
2*t[j]+pos[j]<=2*t[i]+pos[i]且2*t[j]-pos[j]<=2*t[i]-pos[i]
然後按照減法為下標,用加法在樹狀數組上更新即可。
最後,附上醜陋的代碼... ...
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int w,n,f[100010],hash[100010],cnt,ans,s[100010]; struct pies { int t,p,v,w1,w2; }a[100010]; int cmp(const pies &a,const pies &b) { return a.w1<b.w1; } int lowbit(int x){return x&(-x);} int ask(int i) { int Max=0; while (i!=0) { Max=max(Max,s[i]); i-=lowbit(i); } return Max; } void add(int i,int val) { while (i<=cnt) { s[i]=max(s[i],val); i+=lowbit(i); } } int main() { scanf("%d%d",&w,&n); for (int i=1;i<=n;i++) { scanf("%d%d%d",&a[i].t,&a[i].p,&a[i].v); a[i].t*=2; a[i].w1=a[i].t-a[i].p; a[i].w2=a[i].t+a[i].p; hash[++cnt]=a[i].w2; } sort(hash+1,hash+cnt+1); cnt=unique(hash+1,hash+cnt+1)-hash-1; for (int i=1;i<=n;i++) { a[i].w2=lower_bound(hash+1,hash+cnt+1,a[i].w2)-hash; } sort(a+1,a+n+1,cmp); for (int i=1;i<=n;i++) { f[i]=ask(a[i].w2)+a[i].v; ans=max(ans,f[i]); add(a[i].w2,f[i]); } printf("%d\n",ans); return 0; }
小結:無。
[bzoj2131]免費的餡餅_樹狀數組