P1091 合唱队列
合唱队列
原题:传送门
核心代码:
1 /* 2 方法求出每一个点的最长升子序列和最长降子序列,再加到该点上 3 通过循环比较哪个点最大,再用总长减去该点长度即是答案 4 */ 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 int f[2][105]; 10 int a[105]; 11 int ans; 12 13 int main() { 14 int n; 15 cin >> n; 16 for (int i = 1; i <= n; i++) { 17 cin >> a[i]; 18 } 19 a[0] = 0; 20 for (int i = 1; i <= n; i++) { 21 for (int j = 0; j < i; j++) { 22 if (a[i] > a[j]) { //求出从1到n每个点的最长上升子序列 23 f[0][i] = max(f[0][i], f[0][j] + 1); 24 } 25 } 26 } 27 a[n + 1] = 0;//边界值置0 28 for (int i = n; i; i--) { 29 for (int j = n + 1; j > i; j--) {//从n+1开始,因为第n个也算是一个 30 if (a[i] > a[j]) {//求出n到1每个点的最长上升子序列 31 f[1][i] = max(f[1][i], f[1][j] + 1); 32 } 33 } 34 } 35 for (int i = 1; i <= n; i++) { 36 ans = max(ans, f[0][i] + f[1][i] - 1);//-1是去掉中间值,多算了一次 37 } 38 cout << n - ans << endl; 39 return 0; 40 }