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 }
View Code

 

posted @ 2018-04-13 19:07  鲸头鹳  阅读(127)  评论(0编辑  收藏  举报