BZOJ 3963 HDU3842 [WF2011]MachineWorks cdq分治 斜率优化 dp
http://acm.hdu.edu.cn/showproblem.php?pid=3842
写的check函数里写的<但是应该是<=,调了一下午,我是个zz。
就是普通的斜率优化因为有两层需要排序的所以一层sort一层cdq分治
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define LL long long 8 #define pa pair< long long ,long long > 9 const int maxn=100100; 10 int n; 11 LL D,C; 12 struct nod{ 13 LL d,p,r,g,h; 14 }a[maxn]; 15 LL f[maxn]; 16 pa e[maxn],sta[maxn]; 17 bool mcmp(nod aa,nod bb){ 18 return aa.d<bb.d; 19 } 20 bool Chk(pa aa,pa bb,pa cc){ 21 return ((double)((double)(aa.second-bb.second)*(double)(cc.first-bb.first)- 22 (double)(bb.second-cc.second)*(double)(bb.first-aa.first)))>=0; 23 } 24 void mcdq(int l,int r){ 25 if(l==r)return; 26 int mid=(l+r)/2; 27 mcdq(l,mid); 28 int cnt=0,tail=0; 29 for(int i=l;i<=mid;i++){ 30 if(f[i]>=a[i].p){e[++cnt]=make_pair(a[i].g,a[i].h+f[i]);} 31 } 32 sort(e+1,e+1+cnt); 33 for(int i=1;i<=cnt;i++){ 34 while(tail>1&&Chk(sta[tail-1],sta[tail],e[i]))tail--; 35 sta[++tail]=e[i]; 36 }int j=1;//cout<<tail<<endl; 37 for(int i=mid+1;i<=r;i++){ 38 while(j<tail&&sta[j].second+sta[j].first*a[i].d<sta[j+1].second+sta[j+1].first*a[i].d)j++; 39 f[i]=max(f[i],sta[j].second+sta[j].first*a[i].d); 40 } 41 mcdq(mid+1,r); 42 } 43 int main(){ 44 int z=0; 45 while(~scanf("%d%lld%lld",&n,&C,&D)){ 46 if(n==0&&C==0&&D==0)break; 47 f[0]=C; 48 for(int i=1;i<=n;i++){ 49 scanf("%lld%lld%lld%lld",&a[i].d,&a[i].p,&a[i].r,&a[i].g); 50 a[i].h=a[i].r-a[i].p-(a[i].d+1)*a[i].g; 51 }sort(a+1,a+1+n,mcmp);++n; 52 a[n].d=D+1;a[n].g=a[n].p=0; a[n].h=0; 53 for(int i=1;i<=n;i++)f[i]=f[i-1]; 54 mcdq(0,n); 55 printf("Case %d: %lld\n",++z,f[n]); 56 } 57 return 0; 58 }