题意:给你一个整数序列,可以给一个数+1或-1 代价都是1 问最少操作多少次使序列严格递增。
题解:dp+离散 类似于poj3666 只不过原序列a[i]=a[i]-i
然而感觉最终每个数都是原序列中的数,这个结论感觉好魔幻。。。。。。
然后YY了一个比较有道理的推论方法:假如当前序列到i都是递增的 在第i~j个数不再递增,那么第i~j最优整合方案就是向i~j的中位数靠拢,由于中位数一定是原数列中的一个数,那么最优方案中每个数都在原数列中出现过。
#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
int a[3100],b[3100];
long long dp[3100][3100];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),a[i]-=i,b[i]=a[i];
sort(b+1,b+1+n);
for(int i=1;i<=n;i++)
{
long long mn=dp[i-1][1];
for(int j=1;j<=n;j++)
{
mn=min(mn,dp[i-1][j]);
dp[i][j]=mn+abs(a[i]-b[j]);
}
}
long long ans=dp[n][1];
for(int i=2;i<=n;i++) ans=min(ans,dp[n][i]);
cout<<ans;
return 0;
}