需要寻找的是最大的合唱队队形,不一定从头开始 也不一定留下最后一个人。更不是从最高的那个人向左右。
这是一个动态规划的问题。
考虑将每个人身上带两个属性,一个是从左过来的最大的递增数列长度,一个是从右过来的最大的递增数列长度。
两者和最大的那个自然就是合唱队队形中应该保留的身高最高的那个人。
#include<iostream>
using namespace std;int main()
{
int T[255], l[255], r[255];//创建三个数组 T[]存储身高 l[]用作从左遍历 寻找最大递增数列 r[]用作寻找从右寻找最大递增数列
int N, K;//N为总数 K为要剔除的人个数
cin >> N;
for (int i = 0; i<N; i++)
cin >> T[i];
for (int i = 0; i<N; i++)
{
l[i] = 1;//自己即是一个个数为1的递增数列
for (int j = 0; j<i; j++)
if (T[i]>T[j] && l[j] + 1>l[i]) //比较的精髓是从左向右遍历,以遍历到当前身高为被比较对象,若左边有比被比较对象小的身高,看这个身高身上累计的最大递增数列的长度能否大过被比较对象身上类的最大递增数列长度
l[i] = l[j] + 1;//若能 则把此元素加入最大递增数列
}
for (int i = N - 1; i >= 0; i--)//从右遍历
{
r[i] = 1;
for (int j = N - 1; j>i; j--)
if (T[i]>T[j] && r[j] + 1>r[i])
r[i] = r[j] + 1;
}
K = 0;
for (int i = 0; i<N; i++)//每个身高对象带有两个属性,从左遍历和从右遍历的最大递增数列长度。看其和大小即可。
if (l[i] + r[i]>K)
K = l[i] + r[i];
K = N - K + 1;//当前身高计算两次 故要-1
cout << K << endl;
//for (int i = 0; i < n; i++)
// cout << inc[i]<<" ";
//cout << endl;
//for (int i = 0; i < n; i++)
// cout << dec[i]<<" ";
//system("pause");
return 0;
}
- #include<iostream>
- #include<vector>
- using namespace std;
- int main()
- {
- unsigned int number ;
- cin>>number ;
- vector<unsigned int> height(number,0) ; //初始化向量 存储身高
- for(int i=0;i<number;++i)
- {
- cin>>height[i];
- }
- vector<unsigned int>left(number,1) ; //初始化左右最大递增数列长度值 全部置1
- vector<unsigned int>right(number,1) ;
- for(int i=1;i<number;++i) //比较过程并无区别
- {
- for(int j=0;j<i;++j)
- {
- if(height[i]>height[j])
- {
- if(left[i]<left[j]+1)
- {
- left[i]=left[j]+1 ;
- }
- }
- if(height[number-1-i]>height[number-1-j])
- {
- if(right[i]<right[j]+1)
- {
- right[i]=right[j]+1;
- }
- }
- }
- }
- unsigned int count = 0 ;
- unsigned int temp = 0 ;
- for(int i=0;i<number;++i)
- {
- temp=left[i]+right[number-1-i]-1 ;
- if(temp>count)
- {
- count=temp ;
- }
- }
- count = number-count ;
- cout<<count ;
- return 0 ;
- }
- #include<iostream>
- using std::cin ;
- using std::cout ;
- #include<vector>
- using std::vector ;
- int main()
- {
- unsigned int number ;
- cin>>number ;
- vector<unsigned int> height(number , 0) ;
- for(int i=0 ; i<number ; ++i)
- cin>>height[i] ;
- vector<unsigned int> left(number , 1) ;
- vector<unsigned int> right(number , 1) ;
- for(int i=1 ; i<number ; ++i)
- {
- for(int j=0 ; j<i ; ++j)
- {
- if(height[i] > height[j])
- {
- if(left[i] < left[j]+1)
- left[i] = left[j]+1 ;
- }
- if(height[number-1-i] > height[number-1-j])
- {
- if(right[i] < right[j]+1)
- right[i] = right[j]+1 ;
- }
- }
- }
- unsigned int count = 0 ;
- unsigned int temp = 0 ;
- for(int i=0 ; i<number ; ++i)
- {
- temp = left[i] + right[number-1-i] -1 ;
- if(temp > count)
- count = temp ;
- }
- count = number-count ;
- cout<<count ;
- return 0 ;
- }
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <stack>
- #include <queue>
- #include <map>
- #include <cassert>
- #define ll long long int
- #define ull unsigned long long int
- #define MAX(a,b) ((a)>(b))?(a):(b);
- #define MIN(a,b) ((a)<(b))?(a):(b);
- using namespace std;
- int n;
- int a[10000];
- int dp1[10000];
- int dp2[10000];
- int main ()
- {
- while (cin>>n)
- {
- for (int i=1;i<=n;i++)
- cin>>a[i];
- a[0]=-1;
- a[n+1]=-1;
- memset(dp1,0,sizeof(dp1));
- memset(dp2,0,sizeof(dp2));
- dp1[0]=dp2[n+1]=0;
- for (int i=1;i<=n;i++)
- {
- for (int t=0;t<i;t++)
- {
- if (a[i]>a[t])
- {
- dp1[i]=MAX(dp1[i],dp1[t]+1);
- }
- }
- }
- for (int i=n;i>=1;i--)
- {
- for (int t=n+1;t>i;t--)
- {
- if (a[i]>a[t])
- {
- dp2[i]=MAX(dp2[i],dp2[t]+1);
- }
- }
- }
- int ans=0;
- for (int i=0;i<=n;i++)
- ans=MAX(ans,dp1[i]+dp2[i+1]);
- cout<<n-ans<<endl;
- }
- }