有一个结论是,修改成不下降的子序列要求步数最少,那么每个数都应修改成数组中已有的数
(然而这个结论我不太会证,请大神指教)
于是可以dp
先把所有的数放进一个数组b,sort再unique一下
设dp[i][j]表示当前考虑到第i个数,第i个数不超过b[j]的最小修改次数
如果第i个数不是b[j],那么dp[i][j]=dp[i][j-1]
如果第i个数是b[j],那么dp[i][j]=dp[i-1][j]+abs(b[j]-a[i])
两者取max就好了
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <utility>
#include <map>
#include <stack>
#include <set>
#include <vector>
#include <queue>
#include <deque>
#define x first
#define y second
#define mp make_pair
#define pb push_back
#define LL long long
#define Pair pair<int,int>
#define LOWBIT(x) x & (-x)
using namespace std;
const int INF=0x7ffffff;
int n;
int a[5048];
vector<int> v;
LL dp[2][5048];
inline int myabs(int x)
{
return x>=0?x:-x;
}
int main ()
{
int i,j;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
v.pb(a[i]);
}
sort(v.begin(),v.end());
v.resize(unique(v.begin(),v.end())-v.begin());
int p0=0,p1=1;
for (j=0;j<v.size();j++)
if (j==0)
dp[p0][j]=myabs(a[1]-v[j]);
else
dp[p0][j]=min(dp[p0][j-1],(LL)myabs(a[1]-v[j]));
for (i=2;i<=n;i++)
{
for (j=0;j<v.size();j++)
if (j==0)
dp[p1][j]=dp[p0][j]+myabs(a[i]-v[j]);
else
dp[p1][j]=min(dp[p1][j-1],dp[p0][j]+myabs(a[i]-v[j]));
p0^=1;p1^=1;
}
cout<<dp[p0][v.size()-1]<<endl;
return 0;
}