C. Sonya and Problem Wihtout a Legend 題解(dp)
阿新 • • 發佈:2021-08-05
題目連結
題目思路
如果只考慮非嚴格單調上升,那麼必定所有元素變化完之後必定還是屬於原來元素的子集
可以仔細思考下得出
而如果是單調上升,可以讓\(a[i]=a[i]-i\) 然後\(dp\)即可
設\(dp[i][j]\)表示第\(i\)個元素為\(b[j]\)的最小答案
程式碼
卷也卷不過,躺又躺不平#include<bits/stdc++.h> #define fi first #define se second #define debug cout<<"I AM HERE"<<endl; using namespace std; typedef long long ll; const ll INF=0x3f3f3f3f3f3f3f3f; const int maxn=3e3+5,inf=0x3f3f3f3f,mod=1e9+7; const double eps=1e-6; int n; int a[maxn],b[maxn]; ll dp[maxn][maxn]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); a[i]=a[i]-i; b[i]=a[i]; } memset(dp,0x3f,sizeof(dp)); sort(b+1,b+1+n); dp[0][1]=0; for(int i=1;i<=n;i++){ ll mi=INF; for(int j=1;j<=n;j++){ mi=min(mi,dp[i-1][j]); dp[i][j]=min(dp[i][j],mi+abs(a[i]-b[j])); } } ll ans=INF; for(int i=1;i<=n;i++){ ans=min(ans,dp[n][i]); } printf("%lld\n",ans); return 0; }