BZOJ1049:[HAOI2006]数字序列(DP)

Description

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

Input

  第一行包含一个数n,接下来n个整数按顺序描述每一项的键值。n<=35000,保证所有数列是随机的

Output

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

Sample Input

4
5 2 3 5

Sample Output

1
4

Solution

膜拜非凡学长

Code

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #define N (35009)
 5 #define LL long long
 6 using namespace std;
 7 
 8 struct Edge{int to,next;}edge[N];
 9 int n,top,stack[N],f[N],a[N];
10 LL g[N],s1[N],s2[N];
11 int head[N],num_edge;
12 
13 void add(int u,int v)
14 {
15     edge[++num_edge].to=v;
16     edge[num_edge].next=head[u];
17     head[u]=num_edge;
18 }
19 
20 void Solve1()
21 {
22     a[++n]=2e9; stack[0]=-2e9;
23     for (int i=1; i<=n; ++i)
24         if (a[i]>=stack[top]) stack[++top]=a[i],f[i]=top;
25         else
26         {
27             int l=1,r=top,ans=-1;
28             while (l<=r)
29             {
30                 int mid=(l+r)>>1;
31                 if (stack[mid]<=a[i]) l=mid+1;
32                 else ans=mid,r=mid-1;
33             }
34             stack[ans]=a[i]; f[i]=ans;
35         }
36     printf("%d\n",n-top);
37 }
38 
39 void Solve2()
40 {
41     for (int i=n; i>=0; --i)
42         g[i]=2e18,add(f[i],i);
43     a[0]=-2e9; g[0]=0;
44     for (int i=1; i<=n; ++i)
45         for (int j=head[f[i]-1]; j; j=edge[j].next)
46         {
47             int pre=edge[j].to;
48             if (pre>i) break;
49             if (a[pre]>a[i]) continue;
50             s1[pre-1]=s2[pre-1]=0;
51             for (int k=pre; k<=i; ++k)
52             {
53                 s1[k]=s1[k-1]+abs(a[k]-a[pre]);
54                 s2[k]=s2[k-1]+abs(a[k]-a[i]);
55             }
56             for (int k=pre; k<i; ++k)
57                 g[i]=min(g[i],g[pre]+s1[k]-s1[pre]+s2[i]-s2[k]);
58         }
59     printf("%lld\n",g[n]);
60 }
61 
62 int main()
63 {
64     scanf("%d",&n);
65     for (int i=1; i<=n; ++i)
66         scanf("%d",&a[i]),a[i]-=i;
67     Solve1(); Solve2();
68 }
posted @ 2018-10-16 16:55  Refun  阅读(170)  评论(0编辑  收藏  举报