牛客多校(2020第五場)D Drop Voicing
阿新 • • 發佈:2020-08-18
題目連結: https://ac.nowcoder.com/acm/contest/5670/D
題意:
- 給定一個1~n得排列,有倆種操作
- 操作1:可以將倒數第二個數放到開頭
- 操作2:可以將開頭得第一個數放到最後
- 連續若干次操作1(包括1次)成為一段
- 現在要將排序變成1~n,要使得段數儘可能最小,輸出這個最小值
- 2 <= n <= 500
題解:
通過觀察可以發現,我們只需要取環得最長上升子序列,然後用n - 最長上升子序列
1 /* 2 求最大上升子序列 3 */ 4 #include<iostream> 5 #include<algorithm> 6#include<cstring> 7 8 using namespace std; 9 #define INF 0x3f3f3f3f 10 const int N = 505*2; 11 12 int a[N]; 13 int n; 14 15 int LIS(int l, int r) { 16 int dp[N]; 17 fill(dp, dp+N, INF); 18 for (int i = l; i <= r; i++) { 19 *lower_bound(dp+1, dp+n+1, a[i]) = a[i]; 20 }21 int len = lower_bound(dp+1, dp+n+1, INF) - dp - 1; 22 return len; 23 } 24 25 int main() { 26 scanf("%d", &n); 27 for (int i = 1; i <= n; i++) { 28 scanf("%d", &a[i]); 29 a[i+n] = a[i]; 30 } 31 32 int ans = 0; 33 for (int i = 1; i <= n; i++) {34 ans = max(ans, LIS(i, i+n-1)); 35 } 36 printf("%d\n", n - ans); 37 }
參考:https://blog.csdn.net/qq_49528097/article/details/107583809