首页 > 其他 > 详细

倍增优化DP

时间:2019-04-03 15:57:23      阅读:276      评论:0      收藏:0      [点我收藏+]

对于只考虑首位状态的DP,考虑用倍增优化

 

P1081 开车旅行

https://www.luogu.org/problemnew/show/P1081

技术分享图片
 1 const int N=100005;
 2 struct node{int x,y;};
 3 il bool operator <(node a,node b){return a.y<b.y;}
 4 typedef set<node> st;
 5 typedef st::iterator itr;
 6 st s;itr it,lt,rt;
 7 int ii,ga[N],gb[N],t,f[18][N][2],g[10],m,h[N],n,ans;
 8 ll ansA,ansB,a[18][N][2],b[18][N][2],A,B;
 9 
10 il bool cmp(int a,int b)
11 {
12       return abs(h[a]-h[ii]) < abs(h[b]-h[ii]) || (abs(h[a]-h[ii]) == abs(h[b]-h[ii]) && h[a]<h[b]);
13 }
14 
15 il void pre()
16 {
17           n=rd();
18       FOR(i,1,n) h[i]=rd();
19       for(ii=n;ii;--ii)
20     {
21           node p=(node){ii,h[ii]};
22           s.insert(p);
23           it=s.find(p);
24           lt=it,rt=it,m=0;
25           if(lt!=s.begin()) lt--,g[++m]=lt->x;
26           if(lt!=s.begin()) lt--,g[++m]=lt->x;
27           if(rt++,rt!=s.end())
28         {
29               g[++m]=rt->x;
30               if(rt++,rt!=s.end()) g[++m]=rt->x;
31         }    
32           sort(g+1,g+m+1,cmp);
33           if(m) gb[ii]=g[1];
34           if(m>1) ga[ii]=g[2];
35     }
36 }
View Code
 1 il void work()
 2 {
 3     FOR(i,1,n)
 4     {
 5         if(ga[i]) f[0][i][0]=ga[i],a[0][i][0]=abs(h[ga[i]]-h[i]);
 6         if(gb[i]) f[0][i][1]=gb[i],b[0][i][1]=abs(h[gb[i]]-h[i]);
 7     }
 8     t=(int)(log(n*1.0)/log(2.0)+0.001);
 9     FOR(i,1,t) FOR(j,1,n) FOR(k,0,1)
10     {
11         int l;
12         if(i==1) l=k^1; else l=k;
13         if(f[i-1][j][k]) f[i][j][k]=f[i-1][f[i-1][j][k]][l];
14         if(f[i][j][k])
15         {
16             a[i][j][k]=a[i-1][j][k]+a[i-1][f[i-1][j][k]][l];
17             b[i][j][k]=b[i-1][j][k]+b[i-1][f[i-1][j][k]][l];
18         }    
19     }
20 }
技术分享图片
 1 il void solve(int s,int x0,ll &A,ll &B)
 2 {
 3       A=B=0;int k=0;
 4       For(i,t,0)
 5     if(f[i][s][k]&&a[i][s][k]+b[i][s][k]<=x0)
 6     {
 7         x0-=a[i][s][k]+b[i][s][k];
 8         A+=a[i][s][k],B+=b[i][s][k];
 9         if(i==0) k^=1;
10         s=f[i][s][k];
11     }
12 }
13 
14 il void print()
15 {
16       int x0=rd();
17       ansA=1,ansB=0;
18       FOR(i,1,n)
19     {
20           solve(i,x0,A,B);
21           if(!B) A=1;
22           if(A*ansB < B*ansA || (A*ansB==B*ansA && h[i]>h[ans])) ansA=A,ansB=B,ans=i;
23     }
24       printf("%d\n",ans);
25       m=rd();
26       FOR(i,1,m)
27     {
28           int x=rd(),y=rd();
29           solve(x,y,A,B);
30           printf("%lld %lld\n",A,B);
31     }
32 }
33 
34 int main()
35 {
36       pre();
37       work();
38       print();
39       return 0;
40 }
View Code

 

倍增优化DP

原文:https://www.cnblogs.com/universeplayer/p/10649187.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!