1916 Problem C 合唱队形

问题 C: 合唱队形

时间限制: 1 Sec  内存限制: 32 MB
提交: 45  解决: 25
 

题目描述

N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,
则他们的身高满足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1 <= i <= K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入

输入的第一行是一个整数N(2 <= N <= 100),表示同学的总数。
第一行有n个整数,用空格分隔,第i个整数Ti(130 <= Ti <= 230)是第i位同学的身高(厘米)。

输出

可能包括多组测试数据,对于每组数据,
输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

样例输入

3
174 208 219 
6
145 206 193 171 187 167 
0

样例输出

0
1

经验总结

这一题是求最长不降子序列的变形,需要求 dp1 [ i ] (从下标0 开始从前往后 以 i 结尾的最长不增子序列)、dp2 [ i ] (从下标n 开始从后往前 以 i 结尾的最长不增子序列),求完dp1、dp2后,将两个数组对应下标相加求最大max,最终结果则为 n - max + 1(加1的原因是 i 本身在dp1[]和dp2[]里各算了一次,所以多减了一个,要加回去)

正确代码

#include 
#include 
#include 
using namespace std;
const int maxn=110;
int dp1[maxn],dp2[maxn],v[maxn];

int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		if(n==0)
			break;
		for(int i=1;i<=n;++i)
		{
			scanf("%d",&v[i]);
		}
		int num=0;
		for(int i=1;i<=n;++i)
		{
			dp1[i]=1;
			dp2[n+1-i]=1;
			for(int j=1;jv[j]&&dp1[j]+1>dp1[i])
				{
					dp1[i]=dp1[j]+1;
				}
				if(v[n+1-i]>v[n+1-j]&&dp2[n+1-j]+1>dp2[n+1-i])
				{
					dp2[n+1-i]=dp2[n+1-j]+1;
				}
			}
		}
		for(int i=1;i<=n;++i)
		{
			num=max(num,dp1[i]+dp2[i]);
		}
		printf("%d\n",n-num+1);
	}
    return 0;
}

 

你可能感兴趣的:(经验总结)