合唱队形POJ2711

#include <iostream>
#include <stdio.h>
using namespace std;

int inc1[200],inc2[200],a[200];
//inc1-->longest increase array from head to tail
//inc2-->longest increase array from tail to head

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int ans=0,i,j;
        for(i = 0; i < n; i++)  //输入n个人的身高
            scanf("%d",&a[i]);

        //inc1[i]是存储以i为最高点时左边的递增子序列长度
        inc1[0]=1;
        for(i = 1; i < n; i++)
        {
            inc1[i] = 1;
            for(j = 0; j < i; j++)
                if(a[i] > a[j] && inc1[j] + 1 > inc1[i])
                    inc1[i] = inc1[j]+1;
        }

        //inc2[i]是存储以i为最高点时左边的递减子序列长度
        inc2[n - 1] = 1;
        for(i = n - 2; i >= 0; i--)
        {
            inc2[i] = 1;
            for(j = n - 1; j > i; j--)
                if(a[j] < a[i] && inc2[j] + 1 > inc2[i])
                    inc2[i] = inc2[j] + 1;
        }

        for(i = 0; i<=n; i++)
            if(inc1[i] + inc2[i]-1 > ans) 
                ans = inc1[i] + inc2[i] - 1;
        printf("%d\n",n-ans);
    }
    return 0;
}
#include <iostream>
#define N 105
using namespace std;
int n,i,j,ans,up[N],dn[N],a[N];
int main()
{
	cin>>n;
	for(i=1;i<=n;i++)		//输入数据的同时,从左往右求最长上升序列 up[i]
	{
		cin>>a[i];			//输入第i个数 
		for(j=1;j<i;j++)
		  if(a[i]>a[j])
		    up[i]=max(up[i],up[j]+1);	//计算第i个数的上升序列号, 
	}
	for(i=n;i>0;i--)		//从右往左计算最长上升序列dn[i],同时求两次序列的和的最大值ans
	{
	  for(j=n;j>i;j--)
	    if(a[j]<a[i])
	      dn[i]=max(dn[i],dn[j]+1);
	    ans=max(ans,up[i]+dn[i]+1);//ans表示的是要留在合唱队的人数,最长满足要求的人数 
	}
	cout<<n-ans<<endl;				//计算出列的人数 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41045071/article/details/81706728
今日推荐