codeforces 13c dp

题意:一个整数序列,每次操作可以对其中一个数加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;
}

猜你喜欢

转载自blog.csdn.net/qq_38759433/article/details/86556669