zoukankan      html  css  js  c++  java
  • [Baltic2004]sequence

    题目描述:

    给定一个序列t1,t2,...,tn ,求一个递增序列z1<z2<...<zn , 使得R=|t1z1|+|t2z2|+...+|tnzn| 的值最小。本题中,我们只需要求出这个最小的R值。

    样例输入

    7 9 4 8 20 14 15 18

    样例输出

    13

    提示

    所求的Z序列为6,7,8,13,14,15,18.

    R=13

    题解:

    考虑t1>=t2>=t3>=t4这种递减的情况,那么整个z只需取t数组的中位数即可。

    由于z是递增数列,不能全取一样的数。所以我们把t[i]-i;保证z数组就可以取一样的数了 且不会影响答案,因为t[i]-i的同时,求出来z[i]也是减了i的

    那么我们就采取分治的思想,把原数列分成m个递减区间,然后分别取中位数,使得该区间的差值尽量小.

    设X[i]为没个区间的中位数,那么如果X[i]<X[i-1]时不满足z[i]递增的题意,所以要合并,且合并后的答案会更优。(见网上的论文证明)

    以下是详细做法和证明:

    还有一个我的傻逼错误

    ldis()和rdis()没写return 居然函数没有返回值不warning,浪费了很久

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdlib>
     7 using namespace std;
     8 const int N=1000005;
     9 typedef long long ll;
    10 ll gi()
    11 {
    12     ll str=0;char ch=getchar();
    13     while(ch>'9' || ch<'0')ch=getchar();
    14     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
    15     return str;
    16 }
    17 struct node
    18 {
    19     int dis,size,ls,rs;ll x;
    20     node *l,*r;
    21     int ldis(){return l?l->dis:0;}
    22     int rdis(){return r?r->dis:0;}
    23 }T[N];
    24 ll a[N];node *root[N],*pos=T;
    25 ll st[N],top=0;
    26 ll ans=0;
    27 void updata(node *&R)
    28 {
    29     if(R)R->size=(R->l?R->l->size:0)+(R->r?R->r->size:0)+1;
    30 }
    31 node *merge(node *p,node *q)
    32 {
    33     if(!p||!q){return p?p:q;}
    34     if(p->x<q->x)swap(p,q);
    35     if(p->ls>q->ls)p->ls=q->ls;
    36     if(p->rs<q->rs)p->rs=q->rs;
    37     p->r=merge(p->r,q);
    38     if(p->ldis()<p->rdis())swap(p->l,p->r);
    39     p->dis=p->rdis()+1;
    40     updata(p);
    41     return p;
    42 }
    43 void Delet(int x)
    44 {
    45     node *y=root[x]; 
    46     root[x]=merge(root[x]->r,root[x]->l);
    47     root[x]->ls=y->ls;root[x]->rs=y->rs;
    48     y->l=y->r=NULL;y->size=0;
    49 }
    50 int main()
    51 {
    52     int n=gi(),k;
    53     for(int i=1;i<=n;i++){
    54         a[i]=gi()-i;
    55         pos->l=pos->r=NULL;pos->x=a[i];pos->size=1;
    56         pos->ls=pos->rs=i;
    57         root[i]=pos;pos->dis=0;
    58         pos++;
    59     }
    60     int now;
    61     st[++top]=1;
    62     for(int i=2;i<=n;i++){
    63         now=i;
    64         while(top){
    65             k=st[top];
    66             if(root[k]->x>root[now]->x){
    67                 top--;
    68                 root[k]=merge(root[now],root[k]);
    69                 while((root[k]->size<<1)>(root[k]->rs-root[k]->ls+2))Delet(k);
    70                 now=k;
    71                 if(!top){
    72                     st[++top]=now;
    73                     break;
    74                 }
    75             }
    76             else{
    77                 st[++top]=now;
    78                 break;
    79             }
    80         }
    81     }
    82     while(top){
    83         k=st[top];top--;
    84         for(int i=root[k]->ls;i<=root[k]->rs;i++)ans+=abs(root[k]->x-a[i]);
    85     }
    86     cout<<ans;
    87     return 0;
    88 }
  • 相关阅读:
    把影响集中到一个点
    How to avoid Over-fitting using Regularization?
    适定性问题
    Numerical Differentiation 数值微分
    What Every Computer Scientist Should Know About Floating-Point Arithmetic
    Generally a good method to avoid this is to randomly shuffle the data prior to each epoch of training.
    What is the difference between iterations and epochs in Convolution neural networks?
    Every norm is a convex function
    Moore-Penrose Matrix Inverse 摩尔-彭若斯广义逆 埃尔米特矩阵 Hermitian matrix
    perl 类里的函数调用其他类的函数
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6840398.html
Copyright © 2011-2022 走看看