首页 > 题解 > codeforce 13C Sequence

codeforce 13C Sequence


Little Petya likes to play very much. And most of all he likes to play the following game:

He is given a sequence of N integer numbers. At each step it is allowed to increase the value of any number by 1 or to decrease it by 1. The goal of the game is to make the sequence non-decreasing with the smallest number of steps. Petya is not good at math, so he asks for your help.

The sequence a is called non-decreasing if a1 ≤ a2 ≤ … ≤ aN holds, where N is the length of the sequence.

Input
The first line of the input contains single integer N (1 ≤ N ≤ 5000) — the length of the initial sequence. The following N lines contain one integer each — elements of the sequence. These numbers do not exceed 109 by absolute value.

Output
Output one integer — minimum number of steps required to achieve the goal.

Examples
input
5
3 2 -1 2 11
output
4
input
5
2 1 1 1 1
output
1

题意

给定一个序列,每次操作可以把某个数+1-1。要求把序列变成非降数列。而且要求修改后的数列只能出现修改前的数。

题解

定义两个数组a[i]=b[i],将b从小到大排序。

设f[i][j]表示前i个原数组数字,用不超过b[j]形成非降数列的最小花费,则可得出状态方程

$$f[i][j]=min(f[i][j-1],f[i-1][j]+|b[j]-a[i]|);(i>1,j>1);$$

$$f[1][1]=|b[1]-a[1]|;$$

$$f[1][j]=min(f[1][j-1],|b[j]-a[1]|)(j>1);$$

$$f[i][1]=f[i-1][1]+|b[1]-b[i]|(i>1);$$

然后滚动一下

#include <cstdio>
#include <algorithm>
using namespace std;
long long n,a[5010],b[5010],f[5010];
main()
{
    scanf("%lld",&n);
    for (int i=1;i<=n;i++)
        scanf("%lld",&a[i]),b[i]=a[i];
    sort(b+1,b+1+n);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
            if (j==1)
                f[j]+=abs(b[j]-a[i]);
            else
                f[j]=min(f[j-1],f[j]+abs(b[j]-a[i]));
    printf("%lld\n",f[n]);
}