[題解]CF13C Sequence

Sinktank發表於2024-05-01

CF13C Sequence

給定\(N\)個數,每次操作可以選其中一個數\(+1\)\(-1\)。請問要讓這個數列不降,最少需要多少次操作?

我們用DP解決。

\(a\)從小到大排序,存在\(c\)中。

我們用\(f[i][j]\)表示讓前\(i\)個元素滿足條件,而且這些元素最大值不超過\(c[j]\)的最小操作次數。

狀態轉移方程:\(f[i][j]=\min(f[i][j-1],f[i-1][j]+abs(a[i]-c[j]))\)

最終答案就是\(\min(f[n][i])\)

時間複雜度\(O(n^2)\)

注意

  • 空間限制64MB,需要滾動陣列。
  • long long
點選檢視程式碼
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[5010],b[5010];
int f[2][5010];
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b[i]=a[i];
	}
	sort(b+1,b+1+n);
	f[0][0]=f[1][0]=LLONG_MAX;
	bool pos=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			f[pos][j]=min(f[pos][j-1],f[!pos][j]+abs(a[i]-b[j]));
		}
		pos=!pos;
	}
	int ans=LLONG_MAX;
	for(int i=1;i<=n;i++){
		ans=min(ans,f[!pos][i]);
	}
	cout<<ans;
	return 0;
}

附:jiaqiang版P4597 序列 sequence ~ 題解

相關文章