给定一个序列,可以对其中元素进行加一或者减一的操作,问最少多少次操作可以将其转换成非降序列
数论还是弱爆了啊
根据官方题解解释,任意一个序列都存在一个最小非降序列完全由先前序列中的元素构成。
既然知道这个结论这题简单了
f[i][j]表示前i-1个元素为非降序列,第i个元素为先前序列中第j个元素做结尾形成的非降路径所需要的最小代价,由于空间限制,不能用二维数组,则对f进行简化
#include <cstdio> #include <algorithm> using namespace std; long long a[5050], b[5050], f[5050]; int main() { int n;scanf("%d", &n); for (int i = 1; i <= n; ++i) { scanf("%I64d", 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) { f[j] += abs(a[i] - b[j]); if (j > 1) f[j] = min(f[j], f[j - 1]); } } printf("%I64d\n", f[n]); }