其他分享
首页 > 其他分享> > [CF713C] Sonya and Problem Wihtout a Legend - dp

[CF713C] Sonya and Problem Wihtout a Legend - dp

作者:互联网

[CF713C] Sonya and Problem Wihtout a Legend - dp

Description

给定一个数组,每次操作可以把任意一个元素 +1 或者 -1。求使得递增的最小操作次数。 n<=3000

Solution

首先通过 ai=ai-i,转化为单调不降

最终的序列中,一定由若干连续相同的段构成,并且不会出现原序列未出现的数

考虑离散化,设 \(val[i]\) 表示离散化后第 i 个数,设 \(f[i][j]\) 表示将前 i 个数修改成不降,且最后一个数与 \(val[j]\) 相同,需要的代价

前缀最小值维护一下即可

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 3005;

int f[N][N], n, a[N], val[N];

signed main()
{
    ios::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i], a[i] -= i;

    map<int, int> mp;
    for (int i = 1; i <= n; i++)
        mp[a[i]]++;

    int ind = 0;
    for (auto &[x, y] : mp)
        y = ++ind, val[ind] = x;

    for (int i = 1; i <= n; i++)
        a[i] = mp[a[i]];

    for (int i = 1; i <= n; i++)
    {
        int mn = 1e18;
        for (int j = 1; j <= ind; j++)
        {
            mn = min(mn, f[i - 1][j]);
            f[i][j] = mn + abs(val[a[i]] - val[j]);
        }
    }

    cout << *min_element(f[n] + 1, f[n] + ind + 1) << endl;
}

标签:val,int,Wihtout,long,CF713C,ai,Sonya
来源: https://www.cnblogs.com/mollnn/p/14398608.html