2020牛客暑期多校訓練營(第五場)D題Drop Voicing(dp)
阿新 • • 發佈:2020-07-26
2020牛客暑期多校訓練營(第五場)D題Drop Voicing(dp)
題意:長度為n的一個排列,兩種操作,將最前的放到最後,或將最後的前一個放到最前,連續的第二種操作要消耗一費,求變成至小到大的最少費用。
題解:根據本題的規則,很明顯可以發現結合兩種操作可以將操作變成,將任意一個位置的數插入其他位置需要1費,那麼對於一個序列可以固定正確的位置,將每個不正確的位置用費用插入正確的位置既可(正確的位置即從小至大的數),即求最長上升子序列,列舉每一種最長上升子序列既可。
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int n,a[1007],ans,f[1007],sum; int main(){ scanf("%d",&n); sum=0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); a[i+n]=a[i]; } for(int i=1;i<=n;i++){ memset(f,0,sizeof(f)); f[1]=a[i]; ans=1; for(int j=i;j<n+i;j++){ int l=1,r=ans; while(l<=r){ int mid=(l+r)/2; if(f[mid]>=a[j]){ r=mid-1; } else{ l=mid+1; } } f[l]=a[j]; if(l>ans)ans=l; } sum=max(ans,sum); } printf("%d\n",n-sum); }