题目描述

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

输入输出格式

输入格式:

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

输出格式:

第一行一个整数表示最少需要改变多少个数。

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

输入输出样例

输入样例#1:
复制

4
5 2 3 5
输出样例#1: 复制

1
4

说明

【数据范围】

90%的数据n<=6000。

100%的数据n<=35000。

保证所有数列是随机的。

一份讲解的链接

先将数组每一位a[i]减i

这样单调上升就变成了不下降

在给第n+1位加一个正无穷的值(可以做所有子串的结尾,用于统计第2问的答案)

第一问:求最长不下降串长L

答案就是n-L

第二问:首先令f[i]表示1~i的最长不下降长度,g[i]为将1~i变为不下降的代价

对于一对(i,j)且f[i]=f[j]+1

设w(i,j)为将j+1~i变为单调不下降的最小代价

有一个结论:

找到一个断点k

j+1~k全部变成a[j],k+1~i全部变成a[i]

这样一定可以找到这个最小代价

证明见链接

这个复杂度很玄学,最坏O(n^3),但数据是随机的,所以远远达不到

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long lol;
struct Node
{
int next,to;
}edge[];
int L,n,head[],num,Min[],a[];
lol s1[],s2[],g[],f[];
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
int find(int x)
{
int l=,r=L,as=;
while (l<=r)
{
int mid=(l+r)/;
if (Min[mid]<=x) as=mid,l=mid+;
else r=mid-;
}
return as;
}
int main()
{int i,j,k;
cin>>n;
for (i=;i<=n;i++)
{
scanf("%d",&a[i]);
a[i]-=i;
}
++n;
a[n]=(<<);
memset(Min,,sizeof(Min));
Min[]=-<<;L=;
for (i=;i<=n;i++)
{
int t=find(a[i]);
f[i]=t+;
L=max(L,t+);
Min[t+]=min(Min[t+],a[i]);
}
cout<<n-L<<endl;
for (i=n;i>=;i--)
{
add(f[i],i);
g[i]=1ll<<;
}
a[]=-<<;g[]=;
for (i=;i<=n;i++)
{
for (j=head[f[i]-];j;j=edge[j].next)
{
int v=edge[j].to;
if (v>i) break;
if (a[v]>a[i]) continue;
for (k=v;k<=i;k++)
s1[k]=abs(a[k]-a[v]),s2[k]=abs(a[k]-a[i]);
for (k=v+;k<=i;k++)
s1[k]+=s1[k-],s2[k]+=s2[k-];
for (k=v;k<i;k++)
g[i]=min(g[i],g[v]+s1[k]-s1[v]+s2[i]-s2[k]);
}
}
cout<<g[n];
}

最新文章

  1. 【leetcode】Sort Colors(middle)☆
  2. perl常用代码
  3. 修改VS解决方案及工程名,解决如何打开高/版本VS项目
  4. ListView的自动循环滚动显示
  5. POJ 2429
  6. 【Django】基于Django架构网站代码的目录结构
  7. hibernate4.0+版本和3.0+版本的区别总结
  8. ubuntu/deepin制作快捷启动图标
  9. XtraGrid滚轮翻页
  10. 模糊搜索神器fzf
  11. python常用校验方法总结
  12. 虚拟现实外包—动点飞扬软件专门承接VR/AR场景、游戏、项目外包
  13. Reactive Programming
  14. H3C交换机-SNMP配置
  15. ethereum/EIPs-161 State trie clearing
  16. sqlserver binary varbinary image 的区别
  17. Ubuntu 安装 mysql
  18. linux下tomcat运行war包常用命令
  19. 《Head First 设计模式》读书笔记
  20. 【BZOJ1914】数三角形(组合数,极角排序)

热门文章

  1. 201621123050 《Java程序设计》第1周学习总结
  2. 团队作业4——第一次项目冲刺(Alpha版本)11.18
  3. Storm概念讲解和工作原理介绍
  4. Flask 学习 十四 测试
  5. V7000存储数据恢复_底层结构原理拆解及Mdisk磁盘掉线数据恢复方法
  6. JAVA_SE基础——56.包的创建
  7. datable转xml
  8. jenkins 简单实现php集成上线部署
  9. 创建以mybatis为基础的web项目(1)
  10. RSA的公钥、私钥