P1091合唱队形

P1091合唱队形

题目

洛谷题目链接
参考b站视频(讲解非常清晰)

分析

  • 阶段:
    以第i个人为分界,他左边的队列身高递增,右边的队列身高递减
  • 状态:
    考虑第i个人,他和左边能构成的最长上升子序列长度为f(i),从左往右递推
    如果前面的i-1个人中有比他小的则f[i]=f[j]+1 ;
    否则f[i] = 1;
    他和右边能构成的最长下降子序列长度为g(n),从右往左递推
    如果前面的n-i个人中有比他大的则g[i]=g[j]+1;
    否则g[i] = 1;
  • 决策:
    参考最长上升子序列问题,计算f(n)时从左往右递推,计算g(n)时从右往左递推
  • 答案:
    n-max(f[i]+g[i]-1);(减去重复计算的中间那个值)

代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 105;
int main(){
	
	int n,ans,a[maxn],f[maxn],g[maxn];
	cin>>n;
	for(int i = 1;i<=n;i++)
		cin>>a[i];
	
	for(int i = 1;i<=n;i++){
		f[i] = 1;
		for(int j = 1;j<i;j++){
			if(a[j]<a[i])f[i] = max(f[i],f[j]+1);
		}
	}
	for(int i = n;i>=1;i--){
		g[i] = 1;
		for(int j = n;j>i;j--){
			if(a[i]>a[j])g[i] = max(g[i],g[j]+1);
		}
	}
	
	ans = -1;
	for(int i = 1;i<=n;i++){
		ans = max(ans,f[i]+g[i]-1);
	}
	cout<<n-ans<<endl;
	return 0;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值