codevs3250 操作序列

Posted ACforever

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs3250 操作序列相关的知识,希望对你有一定的参考价值。

题目描述 Description

Petya是一个非常好玩孩子。他很无聊,因此他开始玩下面的游戏:

他得到一个长度为N的整数序列,他会对这些数字进行操作,他可以把某个数的数值加1或者减1(当然他可以对同一个数操作很多次)。他的目的是使得数列非递减,即在修改之后,数列满足a1≤a2≤...≤aN 。

请你告诉他,他最少要操作多少次。

输入描述 Input Description

第1行一个整数n。

第2行n个整数 a1、a2、……、an,每两个整数之间用一个空格隔开

输出描述 Output Description

输出只有一行1个整数,表示最少的操作次数。

样例输入 Sample Input

5

3 2 -1 2 11

样例输出 Sample Output

4

数据范围及提示 Data Size & Hint

对于30%的数据  1≤n≤60  的绝对值不超过

对于 60%的数据  1≤n≤200

对于100%的数据1≤n≤5000 的绝对值不超过。

/*
同修路
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll int
using namespace std;
const int maxn = 5005;
const ll inf = ~0U>>1;
struct orz{
    ll p;
    ll v;
};
bool cmp(orz a,orz b){
    return a.v < b.v;
}
ll n,k,a[maxn],dp[maxn][maxn],ans;
orz b[maxn];
inline ll read(){
    char ch=getchar();
    ll f=1,x=0;
    while(!(ch>=0&&ch<=9)){if(ch==-)f=-1;ch=getchar();};
    while(ch>=0&&ch<=9){x=x*10+(ch-0);ch=getchar();};
    return x*f;
}

int main(){
    n = read();
    for(int i = 1;i <= n;i++){
        a[i] = b[i].v = read();
        b[i].p = i;
    }
    sort(b+1,b+1+n,cmp);
    for(int i = 1;i <= n;i++){
        for(int j = 0;j <= n;j++){
            dp[i][j] = inf;
        }
    }
    for(int i = 1;i <= n;i++){
        for(int j = 1;j <= n;j++){
            dp[i][j] = min(dp[i][j],dp[i][j-1]);
            dp[i][j] = min(dp[i][j],dp[i-1][j]+abs(b[j].v-a[i]));
        }
    }
    cout<<dp[n][n]<<endl;
    return 0;
}

 

以上是关于codevs3250 操作序列的主要内容,如果未能解决你的问题,请参考以下文章

CodeVS4665序列终结者

codevs1170 双栈排序

codevs1191数轴染色 序列分块

codevs 5964 [SDOI2017]序列计数

codevs 2010 求后序遍历x

codevs 2622 数字序列