zoukankan      html  css  js  c++  java
  • [luogu2501 HAOI2006] 数字序列 (递推LIS)

    题目描述

    现在我们有一个长度为n的整数序列A。但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列。但是不希望改变过多的数,也不希望改变的幅度太大。

    输入输出格式

    输入格式:
    第一行包含一个数n,接下来n个整数按顺序描述每一项的键值。

    输出格式:
    第一行一个整数表示最少需要改变多少个数。

    第二行一个整数,表示在改变的数最少的情况下,每个数改变的绝对值之和的最小值。

    输入输出样例

    输入样例#1:
    4
    5 2 3 5
    输出样例#1:
    1
    4

    说明

    【数据范围】

    90%的数据n<=6000。

    100%的数据n<=35000。

    保证所有数列是随机的。

    题解

    只会做第一问 比较简单求[a[i]-i]最长不降
    第二问 膜拜题解

    code:

    //By Menteur_Hxy
    #include <map>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define LL long long
    #define M(a,b) memset(a,(b),sizeof(a))
    #define F(i,a,b) for(register int i=(a);i<=(b);i++)
    #define C(i,a,b) for(register int i=(b);i>=(a);i--)
    #define E(i,u) for(register int i=head[u];i;i=nex[i])
    using namespace std;
    
    inline LL rd() {
        LL x=0,fla=1; char c=' ';
        while(c>'9'|| c<'0') {if(c=='-') fla=-fla; c=getchar();}
        while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
        return x*fla;
    }
    
    inline void out(LL x){
        int a[30],wei=0;
        if(x<0) putchar('-'),x=-x;
        for(;x;x/=10) a[++wei]=x%10;
        if(wei==0){ puts("0"); return;}
        for(int j=wei;j>=1;--j) putchar('0'+a[j]);
        putchar('
    ');
    }
    
    const int N=35010;
    const int INF=0x3f3f3f3f;
    int n,tp,cnt,L;
    int b[N],f[N],head[N],to[N],nex[N],mn[N];
    LL g[N],s1[N],s2[N];
    
    void add(int x,int y) {
    	nex[++cnt]=head[x],to[cnt]=y,head[x]=cnt;
    }
    
    int find(int x) { int l=1,r=L,t=0;
    	while(l<=r) { int mid=(l+r)>>1;
    		if(mn[mid]<=x) t=mid,l=mid+1;
    		else r=mid-1;
    	}
    	return t;
    }
    
    void dp() {
    	M(mn,127);
    	mn[0]=-INF;
    	F(i,1,n) { int t=find(b[i]);
    		f[i]=t+1;
    		L=max(L,t+1);
    		mn[t+1]=min(mn[t+1],b[i]);
    	}
    }
    
    int main() {
        n=rd();
        F(i,1,n) b[i]=rd()-i; b[++n]=INF;
        dp();
        C(i,0,n) add(f[i],i),g[i]=(LL)INF;
        g[0]=0;b[0]=-INF;
    	F(x,1,n) E(i,f[x]-1) { int p=to[i];
    		if(p>x) break;
    		if(b[p]>b[x]) continue;
    		F(j,p,x) s1[j]=abs(b[p]-b[j]),s2[j]=abs(b[x]-b[j]);
    		F(j,p+1,x) s1[j]+=s1[j-1],s2[j]+=s2[j-1];
    		F(j,p,x-1) g[x]=min(g[x],g[p]+s1[j]-s1[p]+s2[x]-s2[j]);
    	}
    	out(n-f[n]);out(g[n]);
    	return 0;
    }  
    
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    alpha冲刺9
    alpha冲刺8
    alpha冲刺7
    alpha冲6
    随堂小测-同学录
    alpha冲刺5
    任务3
    任务2
    任务1
    网站用户行为分析
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9159734.html
Copyright © 2011-2022 走看看