首页 > Windows开发 > 详细

AcWing273.分级

时间:2019-05-15 00:14:49      阅读:129      评论:0      收藏:0      [点我收藏+]

题目

给定长度为N的序列A,构造一个长度为N的序列B,满足:

1、B非严格单调,即B1≤B2≤…≤BN或B1≥B2≥…≥BN。
2、最小化 S=∑Ni=1|Ai?Bi|。

只需要求出这个最小值S。

输入格式
第一行包含一个整数N。

接下来N行,每行包含一个整数Ai。

输出格式
输出一个整数,表示最小S值。

数据范围
1≤N≤2000,
1≤|Ai|≤109
输入样例:
7
1
3
2
4
5
3
9
输出样例:
3


代码及思路如下

#include <bits/stdc++.h>
using namespace std;
/**
 * dp[i][j]代表在i的长度下,以j为结尾的最小值
 * dp[i][j] = min(dp[i - 2][z] + abs(arr[i] - j));///z <= j
 * **/
const int MAXN = 2005;
typedef long long ll;
const ll inf = __LONG_LONG_MAX__;
ll arr[MAXN];
ll dp[MAXN][MAXN];
void Init(){
    memset(arr, 0, sizeof(arr));
    memset(dp, 0, sizeof(dp));
}
int n;
vector<ll>vec;
int main(){
    scanf("%d", &n);
    Init();
    vec.clear();
    for(int i = 1; i <= n; i ++){
        scanf("%lld", &arr[i]);
        vec.push_back(arr[i]);
    }
    sort(vec.begin(), vec.end());
    for(int i = 1; i <= n; i ++){
        ll temp = dp[i - 1][1];
        for(int j = 1; j <= n; j ++){
            temp = min(temp, dp[i - 1][j]);
            dp[i][j] = temp + abs(arr[i] - vec[j - 1]);///vec从0开始
        }
    }
    ll re = dp[n][1];
    for(int i = 1; i <= n; i ++){
        re = min(dp[n][i], re);
    }
    printf("%lld\n", re);
    return 0;
}

AcWing273.分级

原文:https://www.cnblogs.com/qq136155330/p/10865412.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!