acwing 273. 分級(線性dp)

傳送門

描述

給定長度爲N的序列A,構造一個長度爲N的序列B,滿足:

1、B非嚴格單調,即B1≤B2≤…≤BN或B1≥B2≥…≥BN。
2、最小化 S=∑Ni=1|Ai−Bi|。

只需要求出這個最小值S。

輸入格式

第一行包含一個整數N。

接下來N行,每行包含一個整數Ai。

輸出格式

輸出一個整數,表示最小S值。

數據範圍

1≤N≤2000,
0≤Ai≤109

輸入樣例:

7
1
3
2
4
5
3
9

輸出樣例:

3

首先,我們先給添加一個排完序的數組,然後對應着位置上升或者下降,這樣能夠保證差的和最小,然後有升序和降序的區別,所以我們正序和

逆序dp一次即可

AC代碼如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn(1e4);
const int inf=0x3f3f3f3f;
int a[maxn],b[maxn],f[maxn][maxn],n,ans=inf;
int dp() {
	for(int i=1; i<=n; i++) {
		int u=inf;
		for(int j=1; j<=n; j++) {
			u=min(u,f[i-1][j]);
			f[i][j]=u+abs(a[i-1]-b[j-1]);
		}
	}
	for(int i=1; i<=n; i++)ans=min(ans,f[n][i]);
}
int main() {
	cin>>n;
	for(int i=0; i<n; i++)
		cin>>a[i],b[i]=a[i];
	sort(b,b+n);
	dp();
	reverse(a,a+n);
	dp();
	cout<<ans<<endl;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章