合唱队

需要寻找的是最大的合唱队队形,不一定从头开始  也不一定留下最后一个人。更不是从最高的那个人向左右。

这是一个动态规划的问题。

考虑将每个人身上带两个属性,一个是从左过来的最大的递增数列长度,一个是从右过来的最大的递增数列长度。

两者和最大的那个自然就是合唱队队形中应该保留的身高最高的那个人。


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

}



  1. #include<iostream>    
  2. #include<vector>    
  3. using namespace std;    
  4.   
  5. int main()    
  6. {    
  7.     unsigned int number ;    
  8.     cin>>number ;    
  9.   
  10.     vector<unsigned int> height(number,0) ;   //初始化向量 存储身高
  11.   
  12.     for(int i=0;i<number;++i)  
  13.     {  
  14.         cin>>height[i];    
  15.     }  
  16.     vector<unsigned int>left(number,1) ;    //初始化左右最大递增数列长度值  全部置1
  17.     vector<unsigned int>right(number,1) ;    
  18.   
  19.     for(int i=1;i<number;++i)    //比较过程并无区别
  20.     {    
  21.         for(int j=0;j<i;++j)    
  22.         {    
  23.             if(height[i]>height[j])     
  24.             {    
  25.                 if(left[i]<left[j]+1)  
  26.                 {  
  27.                     left[i]=left[j]+1 ;    
  28.                 }  
  29.                       
  30.             }    
  31.             if(height[number-1-i]>height[number-1-j])    
  32.             {    
  33.                 if(right[i]<right[j]+1)    
  34.                 {  
  35.                     right[i]=right[j]+1;    
  36.                 }  
  37.             }    
  38.         }    
  39.     }    
  40.     unsigned int count = 0 ;    
  41.     unsigned int temp = 0 ;    
  42.     for(int i=0;i<number;++i)    
  43.     {    
  44.         temp=left[i]+right[number-1-i]-1 ;    
  45.         if(temp>count)  
  46.         {  
  47.             count=temp ;    
  48.         }         
  49.     }    
  50.     count = number-count ;    
  51.     cout<<count ;    
  52.   
  53.     return 0 ;    
  54. }  

  1. #include<iostream>  
  2. using std::cin ;  
  3. using std::cout ;  
  4. #include<vector>  
  5. using std::vector ;  
  6.    
  7.   
  8.   
  9.   
  10. int main()  
  11. {  
  12.     unsigned int  number ;  
  13.     cin>>number ;  
  14.   
  15.     vector<unsigned int> height(number , 0) ;  
  16.   
  17.     for(int i=0 ; i<number ; ++i)  
  18.         cin>>height[i] ;  
  19.   
  20.     vector<unsigned int> left(number , 1) ;  
  21.     vector<unsigned int> right(number , 1) ;  
  22.   
  23.     for(int i=1 ; i<number ; ++i)  
  24.     {  
  25.         for(int j=0 ; j<i ; ++j)  
  26.         {  
  27.             if(height[i] > height[j])   
  28.             {  
  29.                 if(left[i] < left[j]+1)  
  30.                     left[i] = left[j]+1 ;  
  31.             }  
  32.   
  33.   
  34.             if(height[number-1-i] > height[number-1-j])  
  35.             {  
  36.                 if(right[i] < right[j]+1)  
  37.                     right[i] = right[j]+1 ;  
  38.             }  
  39.         }  
  40.   
  41.     }  
  42.   
  43.       
  44.     unsigned int count = 0 ;  
  45.     unsigned int temp = 0 ;  
  46.   
  47.     for(int i=0 ; i<number ; ++i)  
  48.     {  
  49.         temp = left[i] + right[number-1-i] -1 ;  
  50.         if(temp > count)  
  51.             count = temp ;  
  52.     }  
  53.   
  54.     count = number-count ;  
  55.     cout<<count ;  
  56.   
  57.     return 0 ;  
  58. }  

  1. #include <cstdio>  
  2. #include <iostream>  
  3. #include <cstring>  
  4. #include <string>  
  5. #include <algorithm>  
  6. #include <stack>  
  7. #include <queue>  
  8. #include <map>  
  9. #include <cassert>  
  10. #define ll long long int  
  11. #define ull unsigned long long int  
  12. #define MAX(a,b) ((a)>(b))?(a):(b);  
  13. #define MIN(a,b) ((a)<(b))?(a):(b);  
  14.   
  15. using namespace std;  
  16.   
  17. int n;  
  18. int a[10000];  
  19. int dp1[10000];  
  20. int dp2[10000];  
  21.   
  22. int main ()  
  23. {  
  24.     while (cin>>n)  
  25.     {  
  26.         for (int i=1;i<=n;i++)  
  27.             cin>>a[i];  
  28.         a[0]=-1;  
  29.         a[n+1]=-1;  
  30.         memset(dp1,0,sizeof(dp1));  
  31.         memset(dp2,0,sizeof(dp2));  
  32.         dp1[0]=dp2[n+1]=0;  
  33.         for (int i=1;i<=n;i++)  
  34.         {  
  35.             for (int t=0;t<i;t++)  
  36.             {  
  37.                 if (a[i]>a[t])  
  38.                 {  
  39.                     dp1[i]=MAX(dp1[i],dp1[t]+1);  
  40.                 }  
  41.             }  
  42.         }  
  43.         for (int i=n;i>=1;i--)  
  44.         {  
  45.             for (int t=n+1;t>i;t--)  
  46.             {  
  47.                 if (a[i]>a[t])  
  48.                 {  
  49.                     dp2[i]=MAX(dp2[i],dp2[t]+1);  
  50.                 }  
  51.             }  
  52.         }  
  53.         int ans=0;  
  54.         for (int i=0;i<=n;i++)  
  55.             ans=MAX(ans,dp1[i]+dp2[i+1]);  
  56.         cout<<n-ans<<endl;  
  57.     }  
  58. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值