决策单调性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了决策单调性相关的知识,希望对你有一定的参考价值。

决策单调性: 我的理解就是 你每一个F[i] 用于更新它的 F[j] 的 j 的大小,一定不比 F[i-1] 的要靠前。 这就意味着我们可以去维护 一个决策点他作为哪一段区间的决策点时最优

维护时 我们可以 用二分来维护 核心代码:

while(Q[h1].r<j) h1++; // find the point that can be used to update this point
            F[i].push_back(getans(i,j,Q[h1].id));
            while(t2>=h2&&getans(i+1,T[t2].l,T[t2].id)>getans(i+1,T[t2].l,j)) // pop all the element that is useless to update the following points
                T[t2].l=1,T[t2].r=n,T[t2].id=0,t2--; // initally 
            int l=T[t2].l,r=T[t2].r,ans=r+1;
            while(l<=r)// find the point that is ‘special‘ 
            {
                int mid=(l+r)>>1;
                if(getans(i+1,mid,T[t2].id)>getans(i+1,mid,j)) 
                    ans=mid,r=mid-1;
                else l=mid+1;
            }
            if(ans==n+1) continue;
            T[t2].r=ans-1; T[++t2]=(node){ans,n,j}; // update and push_in the new element

 

如何证明决策单调 ? (四边形不等式) 坑待填

xjoi shoes

  1 #include <bits/stdc++.h>
  2 #define int long long
  3 #define N 100010
  4 #define ls c[x][0]
  5 #define rs c[x][1]
  6 using namespace std;
  7 typedef long long ll;
  8 inline int read()
  9 {
 10     int x=0,f=1; char ch=getchar();
 11     while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
 12     while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
 13     return x*f;
 14 }
 15 struct shoes_pair
 16 {
 17     int a,b;
 18 }S[N];
 19 struct node
 20 {
 21     int l,r,id;
 22 }Q[N],T[N];
 23  void print(vector <ll> a){ for(int i=0;i<a.size();i++) cout << a[i] << " "; cout << endl;}
 24 inline bool cmp(const shoes_pair a,const shoes_pair b)
 25 {
 26     return (double(a.a+a.b)/2.0)<(double(b.a+b.b)/2.0);
 27 }
 28 int n,Rt[N],c[N*36][2],ansrl[N*36],size[N*36],anslr[N*36],tot;
 29 int V[N*3],k,h1,t1,h2,t2; map <int,int> M; vector <ll> F[N];
 30 inline void cpy(int x,int y)
 31 {
 32     c[x][0]=c[y][0]; c[x][1]=c[y][1];
 33     size[x]=size[y]; anslr[x]=anslr[y];
 34     ansrl[x]=ansrl[y];
 35 } 
 36 inline void updata(int x,int l,int r,int mid)
 37 {
 38     ansrl[x]=ansrl[ls]+ansrl[rs]+size[rs]*(V[mid+1]-V[l]);
 39     anslr[x]=anslr[ls]+anslr[rs]+size[ls]*(V[r]-V[mid]);
 40     size[x]=size[ls]+size[rs];
 41 } 
 42 int built(int x,int l,int r,int rt)
 43 {
 44     int g=++tot; cpy(g,rt);
 45     if(l==r)
 46     {
 47         ansrl[g]=anslr[g]=0;
 48         size[g]++; return g;
 49     } int mid=(l+r)>>1;
 50     if(mid>=x) c[g][0]=built(x,l,mid,c[g][0]);
 51     if(mid<x) c[g][1]=built(x,mid+1,r,c[g][1]);
 52     updata(g,l,r,mid); 
 53     return g;
 54 }
 55 ll querylr(int x,int l,int r,int rt1,int rt2)
 56 {
 57     if(!(size[rt2]-size[rt1])) return 0; if(l>r) return 0; int mid=(l+r)>>1;
 58     if(x==mid) return anslr[c[rt2][0]]-anslr[c[rt1][0]];
 59     if(x<=mid) return querylr(x,l,mid,c[rt1][0],c[rt2][0]);
 60     return anslr[c[rt2][0]]-anslr[c[rt1][0]]+(size[c[rt2][0]]-size[c[rt1][0]])*(V[x]-V[mid])+
 61            querylr(x,mid+1,r,c[rt1][1],c[rt2][1]);
 62 }
 63 ll queryrl(int x,int l,int r,int rt1,int rt2)
 64 {
 65     if(!(size[rt2]-size[rt1])) return 0; if(l>r) return 0; int mid=(l+r)>>1;
 66     if(x==mid+1) return ansrl[c[rt2][1]]-ansrl[c[rt1][1]];
 67     if(x>mid) return queryrl(x,mid+1,r,c[rt1][1],c[rt2][1]);
 68     return ansrl[c[rt2][1]]-ansrl[c[rt1][1]]+(size[c[rt2][1]]-size[c[rt1][1]])*(V[mid+1]-V[x])+
 69            queryrl(x,l,mid,c[rt1][0],c[rt2][0]);
 70 }
 71 int getmid(int g,int l,int r,int rt1,int rt2)
 72 {
 73     int mid=(l+r)>>1; if(l==r) return l;
 74     if(size[c[rt2][0]]-size[c[rt1][0]]>=g) return getmid(g,l,mid,c[rt1][0],c[rt2][0]);
 75     return getmid(g-size[c[rt2][0]]+size[c[rt1][0]],mid+1,r,c[rt1][1],c[rt2][1]);
 76 }
 77 inline ll getdis(int l,int r)
 78 {
 79     if(l>r) return 0;
 80     int alls=size[Rt[r]]-size[Rt[l-1]];
 81     int x=getmid(alls>>1,1,V[0],Rt[l-1],Rt[r]);
 82     ll ret=querylr(x,1,V[0],Rt[l-1],Rt[r])+queryrl(x,1,V[0],Rt[l-1],Rt[r]);
 83     return ret; 
 84 }
 85 inline ll getans(int i,int j,int t)
 86 {
 87     ll ret=F[i-1][t]+getdis(t+1,j);
 88     return ret;
 89 }
 90 signed main()
 91 {
 92     n=read(); k=read(); for(int i=1;i<=n;i++)
 93         S[i].a=read(),S[i].b=read(),
 94         V[++V[0]]=S[i].a,V[++V[0]]=S[i].b;
 95     sort(S+1,S+1+n,cmp); sort(V+1,V+1+V[0]);
 96     V[0]=unique(V+1,V+1+V[0])-V-1;
 97     for(int i=1;i<=V[0];i++) M[V[i]]=i;
 98     for(int i=1;i<=n;i++) S[i].a=M[S[i].a],S[i].b=M[S[i].b];
 99     for(int i=1;i<=n;i++)
100         Rt[i]=built(S[i].a,1,V[0],Rt[i-1]),
101         Rt[i]=built(S[i].b,1,V[0],Rt[i]);
102     F[0].push_back(0); ll ans=10000000000000000ll;
103     for(int i=1;i<=n;i++) F[0].push_back(ans); 
104     h1=1; t1=0; Q[++t1]=(node){1,n,0};
105     for(int i=1;i<=k;i++)
106     {
107         F[i].push_back(0); h2=1; t2=0;
108         T[++t2]=(node){1,n,0};
109         for(int j=1;j<=n;j++)
110         {
111             while(Q[h1].r<j) h1++;
112             F[i].push_back(getans(i,j,Q[h1].id));
113             while(t2>=h2&&getans(i+1,T[t2].l,T[t2].id)>getans(i+1,T[t2].l,j)) 
114                 T[t2].l=1,T[t2].r=n,T[t2].id=0,t2--;
115             int l=T[t2].l,r=T[t2].r,ans=r+1;
116             while(l<=r)
117             {
118                 int mid=(l+r)>>1;
119                 if(getans(i+1,mid,T[t2].id)>getans(i+1,mid,j)) 
120                     ans=mid,r=mid-1;
121                 else l=mid+1;
122             }
123             if(ans==n+1) continue;
124             T[t2].r=ans-1; T[++t2]=(node){ans,n,j};
125         }
126         ans=min(ans,F[i][n]);
127         t1=t2; h1=h2;
128         for(int j=h1;j<=t1;j++) Q[j]=T[j];
129     }
130     cout << ans << endl;
131     
132     return 0;
133 }

 

bzoj 诗人小G

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef long double ldb;
 5 const ll limit=(ll)1e18;
 6 inline int read()
 7 {
 8     int x=0,f=1; char ch=getchar();
 9     while(ch<0||ch>9){if(ch==-)f=-1; ch=getchar();}
10     while(ch>=0&&ch<=9){x=x*10+ch-0; ch=getchar();}
11     return x*f;
12 }
13 struct node
14 {
15     int id,l,r;
16 }Q[100010];
17 ldb F[100010];
18 ll sum[100010];
19 int t,n,L,p,hd,tl; char sd[50];
20 ldb qpow(ldb bas,int pw)
21 {
22     ldb ret=1;
23     while(pw--)
24     {
25         ret*=bas; 
26     }
27     return ret;
28 }
29 ldb get(int x,int y)
30 {
31     ldb ret=F[y]+qpow(fabs(sum[x]-sum[y]+x-y-1-L),p);
32     return ret;
33 }
34 int main()
35 {
36     //freopen("read.in","r",stdin);
37     scanf("%d",&t);
38     while(t--)
39     {
40         scanf("%d%d%d",&n,&L,&p);
41         sum[0]=0;
42         for(int i=1;i<=n;i++)
43         {
44             scanf("%s",sd);
45             sum[i]=sum[i-1]+strlen(sd);
46         }
47         hd=1; tl=0; Q[++tl]=(node){0,1,n};
48         for(int i=1;i<=n;i++)
49         {
50             while(Q[hd].r<i) hd++;
51             F[i]=get(i,Q[hd].id);
52             while(get(Q[tl].l,i)<get(Q[tl].l,Q[tl].id)&&tl>=hd) Q[tl].id=0,Q[tl].l=1,Q[tl].r=n,tl--;
53             int lls=Q[tl].l,rr=Q[tl].r,ans=rr+1;
54             while(lls<=rr)
55             {
56                 int mid=(lls+rr)>>1;
57                 if(get(mid,i)<get(mid,Q[tl].id)) 
58                     ans=mid,rr=mid-1;
59                 else lls=mid+1;
60             }
61             if(ans==n+1) continue;
62             Q[tl].r=ans-1; Q[++tl].l=ans; Q[tl].r=n; Q[tl].id=i;
63         }
64         if(F[n]>limit) printf("Too hard to arrange\n");
65         else printf("%.0Lf\n",F[n]);
66         puts("--------------------");
67     }
68     return 0;
69 }

 

以上是关于决策单调性的主要内容,如果未能解决你的问题,请参考以下文章

决策单调性

决策单调性优化dp

决策单调性优化dp 专题练习

bzoj 2216 [Poi2011]Lightning Conductor 决策单调性+dp

luogu P6087 [JSOI2015]送礼物 二分 单调队列 决策单调性

单调性优化学习笔记