1. 程式人生 > >bzoj2131: 免費的餡餅

bzoj2131: 免費的餡餅

change == main owb family ace node cmp col

首先我們很容易看出是一個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]<p[j] -> t[i]*2+p[i]>=t[j]*2+p[j]

這樣的話我只會樹套樹(後來想想帶修主席樹應該也行?)。。。。。信仰不夠去%題解

結果發現這兩個東西是可以放在一起的,也就是說如果滿足p[i]>p[j]和t[i]*2-p[i]>=t[j]*2-p[j]那t[i]*2+p[i]>=t[j]*2+p[j]也滿足(好像很顯然啊是我柿子畫得太醜看不出來嗎)

就成了水水的二維偏序了。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int s[110000];
int lowbit(int x){return x&-x;}
void change(int x,int k)
{
    while(x<=100010)
    {
        s[x]
=max(s[x],k); x+=lowbit(x); } } int getmax(int x) { int ret=0; while(x>0) { ret=max(ret,s[x]); x-=lowbit(x); } return ret; } struct node{int w1,w2,v;}a[110000]; bool cmp(node n1,node n2){return n1.w1==n2.w1?n1.w2<n2.w2:n1.w1<n2.w1;}
int lslen,ls[110000]; int main() { int W,n,t,p; scanf("%d%d",&W,&n); for(int i=1;i<=n;i++) { scanf("%d%d%d",&t,&p,&a[i].v); a[i].w1=t*2-p; a[i].w2=t*2+p; ls[++lslen]=a[i].w2; } sort(a+1,a+n+1,cmp); sort(ls+1,ls+lslen+1); lslen=unique(ls+1,ls+lslen+1)-ls-1; for(int i=1;i<=n;i++) a[i].w2=lower_bound(ls+1,ls+lslen+1,a[i].w2)-ls; for(int i=1;i<=n;i++)change(a[i].w2,getmax(a[i].w2)+a[i].v); printf("%d\n",getmax(lslen)); return 0; }

bzoj2131: 免費的餡餅