AcWing 273. 分级 (线性DP)

AcWing 273. 分级

给定长度为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

题目大意:

先给一个长度为N的序列,在A中选取N个数,组成非严格单调的序列B,(这里是可以取重复的数字,一开始理解错误,以为不能取相同的数字,导致样例解释错误),求最小的S=∑Ni=1|Ai−Bi|

题目分析:

这里我们可以用一个dp[ i ][ j ]数组,表示处理了前 i 位的情况下,第 j 位的最小更改数,当Bi = j 时,S的值最小。
故我们可以得到我们的动态转移方程:

dp [ i ][ j ] = min{ dp[ i - 1][k] + | a[i] - j | }, (0 <= k <= j);

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
#include <stack>
#define maxn 2005
#define INF 0x3f3f3f3f
using namespace std;

typedef long long ll;

int n;
int a[maxn],Bup[maxn],Bdown[maxn];
ll dpup[maxn][maxn],dpdown[maxn][maxn];

int cmp(int a, int b)
{
     
    return a > b;
}

int main()
{
     
    while(cin >> n)
    {
     
        memset(dpdown, 0, sizeof(dpdown));
        memset(dpup, 0, sizeof(dpup));
        for(int i = 1; i <= n; i ++)
        {
     
            cin >> a[i];
            Bup[i] = a[i];
            Bdown[i] = a[i];
        }

        sort(Bup + 1, Bup + 1 + n);
        sort(Bdown + 1, Bdown + 1 + n, cmp);

        for(int i = 1; i <= n; i ++)
        {
     
            ll minn = INF;
            for(int j = 1; j <= n; j ++)
            {
     
                minn = min(minn, dpup[i - 1][j]);
                dpup[i][j] = minn + fabs(a[i] - Bup[j]);
            }
        }

        for(int i = 1; i <= n; i ++)
        {
     
            ll minn = INF;
            for(int j = 1; j <= n; j ++)
            {
     
                minn = min(minn, dpdown[i - 1][j]);
                dpdown[i][j] = minn + fabs(a[i] - Bdown[j]);
            }
        }
        ll up = INF;
        ll down = INF;

        for(int i = 1; i <= n; i ++)
            up = min(up, dpup[n][i]);
        for(int i = 1; i <= n; i ++)
            down = min(down, dpdown[n][i]);        

        ll ans = min(up, down);
        cout << ans << endl;
    }
    return 0;
}

你可能感兴趣的:(做题记录DP,算法竞赛进阶指南,个人练习记录)