题意:一个整数序列,每次操作可以对其中一个数加1或者减1,求把这个序列变成非减序列所需的最少操作次数。
题解:首先有一个结论:如果要使修改成不下降的子序列要求步数最少,那么每个数都应修改成数组中已有的数
状态转移方程 f[i][j]=min(f[i-1][j]+abs(a[i]-b[j]),f[i][j-1]),f[i][j]表示把前i个数变成递增序列,第i个数变成b[j]的最少步数。
把第j个数是否等于b[j]分类即可得到
#include <bits/stdc++.h>
using namespace std;
long long f[5005];
int a[5005], b[5005];
int main(){
int n;
while(scanf("%d", &n) != EOF){
for(int i = 0; i <= n; i ++)
f[i] = 0;
for(int i = 1; i <= n; i ++){
scanf("%d", &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 - 1], f[j]);
}
cout << f[n] << endl;
}
return 0;
}