题目描述
计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<…<Ti-1Ti+1>…>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
注意不允许改变队列元素的先后顺序
请注意处理多组输入输出!
输入描述:
整数N
输出描述:
最少需要几位同学出列
示例1
输入
8
186 186 150 200 160 130 197 200
输出
4
题目讲解
最长递增子序列1
最长递增子序列2
scanf()函数不能输入带有空格的字符串,但是可以输入带有空格的int数据,其中会吃掉空格。
函数的局部变量作为返回值
未通过代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 300
int temp[N];
int max_int(int a, int b)
{
int max;
return max = (a > b ? a : b);
}
int *getResult(int n, int arr[])
{
temp[0] = 1;
for (int i = 1; i < n; i++)
{
int cnt = 1;//dp[i] 默认都为 1,因为以 i 结尾的 LIS 至少包含自己,且必须放在这里,不能放到for外面
for (int j = i - 1; j >= 0; j--)
{
if (arr[i] > arr[j])
{
cnt = max_int(cnt, temp[j] + 1);
}
}
temp[i] = cnt;
}
return temp;
/*不能直接返回数组,需借助全局变量,此时不用return
或者返回数组首地址(此时需要return temp) */
}
int main(void)
{
int n;
while (scanf("%d", &n) != EOF)
{
int *dp=NULL, *dq=NULL;
int stu1[N], stu2[N];
int max_stu = 1;
for (int i = 0, j = n; i < n; i++, j--)
{
scanf("%d", &stu1[i]);
}
for (int j = n-1,i=0; j >=0; j--)
{
//int i = 0;
stu2[j] = stu1[i];
i++;
}
dp = (int *)malloc((n+1) * 4);
dq = (int *)malloc((n+1) * 4);
dp = getResult(n, stu1);
dq = getResult(n, stu2);
for (int i = 0,j=n-1; i < n; i++,j--)
{
max_stu = max_int(max_stu, dp[i] + dq[j]);
}
printf("%d\n", n - (max_stu - 1));
free(dp);
dp = NULL;
free(dq);
dq = NULL;
}
return 0;
}