题意:
N个数。a1...aN。
对于每个数而言,每一步只能加一或减一。
问最少总共需要多少步使得新序列是非递减序列。
N (1 ≤ N ≤ 5000)
思路:
*一个还不知道怎么证明的结论(待证):最后的新序列b1...bN中的每一个数bi,一定是原a1..aN序列中的某个数。
将a1..aN从小到大排列,得到c1...cN。
dp[i][j]:原序列前i个数经过操作,第i个数不超过c[j]所花最少步数。
dp[i][j]=min( dp[i-1][j]+abs(a[i]-b[j]),dp[i][j-1] )
然后用滚动数组。
代码:
int const N=5005; int n; ll a[N],b[N]; ll dp[N]; int main(){ cin>>n; rep(i,1,n){ scanf("%I64d",&a[i]); b[i]=a[i]; } mem(dp,0); dp[0]=INF; sort(b+1,b+1+n); rep(i,1,n){ //前i个 rep(j,1,n){ //最后一个高度不超过第b[j]个的高度 dp[j]=min( dp[j]+abs(a[i]-b[j]),dp[j-1] ); } } ll ans=INF; rep(i,1,n){ ans=min(ans,dp[i]); } printf("%I64d\n",ans); return 0; }
时间: 2024-10-16 01:18:59