1、DP写法
f [ i ] 表示以 i 结尾的子序列的最长长度。
g [ i ] 表示从尾部出发,以 i 结尾的子序列的最长长度。
那么假设选定 i 为最高点的话,合唱队形人数为f [ i ] + g [ i ] - 1 ,减一是因为 i 算了两次。
1 #include<iostream> 2 using namespace std; 3 const int N=110; 4 int a[N],f[N],g[N]; 5 int main(void){ 6 int n; 7 cin>>n; 8 for(int i=1;i<=n;i++){ 9 cin>>a[i]; 10 } 11 for(int i=1;i<=n;i++){//正着做一遍最长子序列 12 f[i]=1; 13 for(int j=1;j<i;j++){ 14 if(a[i]>a[j]){ 15 f[i]=max(f[i],f[j]+1); 16 } 17 } 18 } 19 20 for(int i=n;i>=1;i--){//反着做一遍最长子序列 21 g[i]=1; 22 for(int j=n;j>i;j--){ 23 if(a[i]>a[j]){ 24 g[i]=max(g[i],g[j]+1); 25 } 26 } 27 } 28 int res=0; 29 for(int i=1;i<=n;i++){//统计答案 30 res=max(res,f[i]+g[i]-1); 31 } 32 cout<<n-res; 33 return 0; 34 }
2、优化写法(贪心)
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int N=110; 5 int a[N],f[N],g[N],d[N]; 6 int main(void){ 7 int n; 8 cin>>n; 9 for(int i=1;i<=n;i++){ 10 cin>>a[i]; 11 } 12 13 //求f 14 memset(d,0,sizeof(d)); 15 d[0]=0; 16 int len=0; 17 for(int i=1;i<=n;i++){ 18 int l=0,r=len; 19 while(l<r){ 20 int mid=l+r+1>>1; 21 if(d[mid]<a[i]) l=mid; 22 else r=mid-1; 23 } 24 len=max(len,r+1); 25 f[i]=r+1; 26 d[r+1]=a[i]; 27 } 28 29 //求g 30 memset(d,0,sizeof(d)); 31 len=0; 32 for(int i=n;i>=1;i--){//必须从后往前,依据题意要求的g是从尾部到i的上升序列的最大长度 33 //而从前往后算递减的话(假设g[1]最大)g[1]=1,而他应该为n的。 34 int l=0,r=len; 35 while(l<r){ 36 int mid=l+r+1>>1; 37 if(d[mid]<a[i]) l=mid; 38 else r=mid-1; 39 } 40 len=max(len,r+1); 41 g[i]=r+1; 42 d[r+1]=a[i]; 43 } 44 45 46 //统计答案 47 int res=0; 48 for(int i=1;i<=n;i++){ 49 res=max(res,f[i]+g[i]-1); 50 } 51 cout<<n-res; 52 53 return 0; 54 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端