华为机试HJ24-合唱队

题目描述

计算最少出列多少位同学,使得剩下的同学排成合唱队形

说明:

N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1…>TK。

你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

注意不允许改变队列元素的先后顺序
请注意处理多组输入输出!

输入描述:

整数N

输出描述:
最少需要几位同学出列

示例1

输入

8
186 186 150 200 160 130 197 200

输出

4

题目讲解
最长递增子序列1
最长递增子序列2
scanf()函数不能输入带有空格的字符串,但是可以输入带有空格的int数据,其中会吃掉空格。
函数的局部变量作为返回值

未通过代码:

#include 
#include 
#include 

#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;
}


你可能感兴趣的:(华为机试在线练习(牛客网))