合唱队形(LIS)

在这里插入图片描述

思路:从题意我们可以发现求一个金字塔形的序列,那么我们就从左往右 ,从右往左求2次最长上升子序列,再遍历一遍可求出最长的金字塔形序列。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include<iostream>
#include<vector>
#include<queue>
//#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
const int mod=1e9+7;
const int N=2e6+10;
const int M=1e5+10;
const int inf=0x7f7f7f7f;
const int maxx=2e5+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 题目描述: 给定一个长度为 n 的同学身高序列,要求在其中取出 kk 位同学排成合唱队,要求先从左往右依次选择下标递增的 kk 位同学,然后从右往左依次选择下标递减的 kk 位同学,且中间位置的同学既能属于左边也能属于右边,求最多能有多少位同学同时在合唱队里,输出这个最大值。 解题思路: 针对这道题,可以采用动态规划的思路来解决。动态规划决策:以第 ii 个同学为结尾的最长上升子序列长度 Lis(i),以第 ii 个同学为开头的最长下降子序列长度 Lds(i),加起来再减去 11(因为 ii 这个同学被重复计算了一次)即为以 ii 为山顶信息的 LDS 长度。其状态转移方程为: Lis(i)=max(Lis(j))+1,j<i,a[i]>a[j]; 其中 a[i]>a[j] 前提是整个序列是上升的。如果 a[i]>a[j] 条件不满足的话,那么 Lis(i)=1。 Lds(i)=max(Lds(j))+1,j>i,a[i]>a[j] 其中 a[i]>a[j] 前提是整个序列是下降的。如果 a[i]>a[j] 条件不满足的话,那么 Lds(i)=1。 最后,遍历所有的 ii 并求出以第 ii 个同学为山顶的 LDS 长度即可。 实现过程中需要注意的点: - 在实现 Lis 和 Lds 函数时需要注意,需要将第一项设为 1,因为一个人也能组成一个队伍。 - 动态规划实现时需要用到两个数组,分别记录 Lis 和 Lds 的结果。 参考代码: ### 回答2: 这道题可以用动态规划来解决。设数组up[i]表示以i结尾的最长上升子序列长度,数组down[i]表示以i开始的最长下降子序列长度,则最终的答案为max{up[i]+down[i]-1}(1<=i<=n)。 首先,我们可以先计算出所有以i结尾的最长上升子序列长度up[i]。考虑到求以i结尾的最长上升子序列,我们可以从1~i-1枚举j,如果a[j]<a[i],则up[i]=max{up[i],up[j]+1}。这个过程可以使用动态规划来实现,时间复杂度为O(n^2)。 然后,我们再计算出所有以i开始的最长下降子序列长度down[i]。考虑到求以i开始的最长下降子序列,我们可以从n到i+1枚举j,如果a[j]<a[i],则down[i]=max{down[i],down[j]+1}。同样,这个过程也可以使用动态规划来实现,时间复杂度也为O(n^2)。 最终,我们可以从1~n枚举i,求出up[i]+down[i]-1的最大值,即为答案。 此外,题目中要求出列的同学人数,可以使用贪心算法,从up[i]+down[i]-1最大的位置i开始,先选择up[i]最大的k位同学出列,再选择down[i]最大的k位同学出列,总共出列2k位同学。之后剩下的同学即可排成合唱队。 总体时间复杂度为O(n^2)。 ### 回答3: 这是一个典型的动态规划问题。首先需要明确状态。我们可以将状态定义为:dp[i][j]表示以第i名学生为结尾,已经选择j个学生出列,所得到的合唱队的最大长度。 然后考虑状态转移方程。对于第i名学生,有两种选择:出列或不出列。如果第i名学生不出列,则dp[i][j]可以由dp[i-1][j]转移而来。如果第i名学生出列,则需要考虑所有比他低的学生中已经出列的人数,假设为p,则dp[i][j]可以由max{dp[k][j-p]+1}(1≤k<i)转移而来。 最终答案为所有dp[i][j]中最大的值。 需要注意的是,一定要先将所有学生按身高排序,这样才能满足合唱队的定义。同时,合唱队的长度应该大于等于2,因此出列的人数j应该在1~n-1之间。 代码如下: (其中INF表示一个足够大的数,用于初始化)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值