482. 合唱队形

NNN位同学站成一排,音乐老师要请其中的(N−K)(N-K)(N−K)位同学出列,使得剩下的KKK位同学排成合唱队形。

合唱队形是指这样的一种队形:设KKK位同学从左到右依次编号为1,2…,K,1,2…,K,1,2…,K,他们的身高分别为T1,T2,…,TKT_1,T_2,…,T_KT1​,T2​,…,TK​,  则他们的身高满足T1<…<Ti>Ti+1>…>TK(1≤i≤K)T_1<…<T_i>T_{i+1}>…>T_K(1≤i≤K)T1​<…<Ti​>Ti+1​>…>TK​(1≤i≤K)。

你的任务是,已知所有NNN位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入格式
输入的第一行是一个整数NNN,表示同学的总数。

第二行有nnn个整数,用空格分隔,第iii个整数TiT_iTi​是第iii位同学的身高(厘米)。

输出格式
输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

数据范围
2≤N≤1002≤N≤1002≤N≤100,
130≤Ti≤230130≤T_i≤230130≤Ti​≤230
输入样例:

8
186 186 150 200 160 130 197 220

输出样例:

4

思路:

T1<…<Ti>Ti+1>…>TK(1≤i≤K)T_1<…<T_i>T_{i+1}>…>T_K(1≤i≤K)T1​<…<Ti​>Ti+1​>…>TK​(1≤i≤K)表示了三种情况。

  1. i = 1,TiT_iTi​就是第一个数,故这是一个完全递减序列。
  2. i = k,TiT_iTi​就是最后一个数,故这是一个完全递增序列。
  3. i1~k之间,则TiT_iTi​是位于序列中间的最大的数,左边递增的序列,右边递减的序列。

算法如下

(线性DP,最长上升子序列) O(n2)O(n^2)O(n2)
假设最优解的中心是第 i个人,则 T1,T2,…,TiT_1,T_2,…,T_iT1​,T2​,…,Ti​一定是以 TiT_iTi​结尾的最长上升子序列。
同理,Ti,Ti+1,...TKT_i,T_{i+1},...T_KTi​,Ti+1​,...TK​一定是以 TKT_KTK​结尾的最长下降子序列,而从前往后的最长下降子序列可以转换为求从后往前的最长上升子序列。

因此可以先预处理出:

从前往后以每个点结尾的最长上升子序列长度 f[i]
从后往前以每个点结尾的最长上升子序列长度 g[i]
那么以 k 为中心的最大长度就是 f[k] + g[k] - 1(因为在求以TKT_KTK​结尾的最长子序列时,f[k]g[k]都包含了TKT_KTK​,故要减去一个),遍历 k = 1, 2, ..., n 取最大值即为答案。

求最长上升子序列的算法:

可参考 LeetCode 300 .最长递增子序列

动态规划:
1、确定状态,对于最优的策略,一定有最后一个元素nums[i],最长上升子序列最短是1,就是当前元素本身,当子序列长度大于1的时候,那么最终最优策略里面的nums[i]的前一个元素是nums[j],即剔除了j~i之间的其他元素,因为是最优策略,所以他选中的以nums[j]结尾的上升子序列一定是0~j中最长的子序列。
2、转移方程: dp[i]表示以nums[i]结尾的最长上升子序列的长度,当i>j&&nums[i] > nums[j]时,dp[i] = max{dp[i],dp[j]+1}
3、初始状态:每个dp[i]开始至少是1
4、计算顺序,下标由小到大,我们需要的dp[k]即以第k个元素结尾的最长上升子序列。

LeetCode 300 .最长递增子序列 Java代码

class Solution {public int lengthOfLIS(int[] nums) {if(nums==null || nums.length==0) return 0;int[] dp = new int[nums.length];int res = 0;//保存本轮外层for循环产生的最大的上升子序列长度for(int i = 0;i<nums.length;i++){dp[i] = 1;//初始至少为1for(int j = 0;j<i;j++){//计算j之前的所有最长的,看其+1后是否大于dp[j]if(nums[i] > nums[j] ){dp[i] = Math.max(dp[i],dp[j] + 1);}}res = Math.max(res,dp[i]);}return res;}
}

本题Java代码

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int[] nums = new int[n];int[] f = new int[n];int[] g = new int[n];for(int i = 0;i < n;i++){nums[i] = scanner.nextInt();}//求最长上升子序列的动态数组f[n]for(int i = 0;i < n;i++){f[i] = 1;for(int j = 0;j < i;j++){if(nums[i] > nums[j]){f[i] = Math.max(f[i],f[j] + 1);}}}//求最长下降子序列的动态数组g[n],反着求最长上升子序列即可for(int i = n - 1;i >= 0;i--){g[i] = 1;for(int j = n -1;j > i;j--){if(nums[i] > nums[j]){g[i] = Math.max(g[i],g[j] + 1);}}}//求出以每一个Tk作为最高点时,能留下多少同学,取最大值int res = Integer.MIN_VALUE;for(int k = 0;k < n;k++){res = Math.max(res,f[k] + g[k] - 1);}//输出应该出列多少同学System.out.println(n - res);}
}

day19 482 合唱队形 (线性DP)相关推荐

  1. P1091 合唱队形[单调性+DP]

    题目来源:洛谷 题目描述 N位同学站成一排,音乐老师要请其中的(N−K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,-,K,他们的身高 ...

  2. 【OpenJ_Bailian - 2711 】 合唱队形(dp,枚举中间顶点)

    题干: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形.  合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, -, K,他们的 ...

  3. 【动态规划刷题笔记】线性dp:合唱队形(最长递增子序列的变体)

    [NOIP2004 提高组] 合唱队形 - 洛谷 思路:最少出列,即挑出最多,即找最长递增子序列和最长递减子序列 设dp1[i]为以h[i]结尾的最长递增子序列 dp2[i]为以h[i]开头的最长递减 ...

  4. UOJ #214 合唱队形 (概率期望计数、DP、Min-Max容斥)

    UOJ #214 合唱队形 (概率期望计数.DP.Min-Max容斥) 9个月的心头大恨终于切掉了!!!! 非常好的一道题,不知为何uoj上被点了70个差评. 题目链接: http://uoj.ac/ ...

  5. tyvj 1067 合唱队形 dp LIS

    P1067 合唱队形 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2004 提高组 第三道 描述 N位同学站成一排,音乐老师要请其中的(N-K)位 ...

  6. 【DP】合唱队形(jzoj 1122)

    合唱队形 jzoj 1122 题目大意: 有n个人,按一定的顺序站成一排,最少减去多少个人可以使队列以一个人为中心,两边分别递减 输入样例 8 186 186 150 200 160 130 197 ...

  7. 动态规划 —— 线性 DP

    [概述] 线性动态规划,是较常见的一类动态规划问题,其是在线性结构上进行状态转移,这类问题不像背包问题.区间DP等有固定的模板. 线性动态规划的目标函数为特定变量的线性函数,约束是这些变量的线性不等式 ...

  8. 合唱队形(递增再递减的最长子序列)

    题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, -, K,他们的 ...

  9. P1091 合唱队形(LIS)

    题目描述 NNN位同学站成一排,音乐老师要请其中的(N−KN-KN−K)位同学出列,使得剩下的KKK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,-,K1,2, ...

  10. LuoGU 线性DP

    P1091 合唱队形 看一下题解吧,你好i需要正反搜一下lcs ,然后合并 #include<bits/stdc++.h> using namespace std; #define LOA ...

最新文章

  1. web developer tips (39):在Visual Studio 2008中取消远程web操作
  2. 《漫画算法2》源码整理-1 二分查找树 AVL树 红黑树
  3. 九、“行胜于言车胜马,负重致远向前途”
  4. catkin_make与gtest出现冲突的问题与解决
  5. USACO-Section1.3 Transformations (矩阵旋转匹配问题)
  6. LVS NAT 模型配置实例
  7. 设计师需要的素材网站,给你归纳好了,拿走!
  8. Debug调试工具使用
  9. 2021费控报销领域最具商业合作价值企业盘点
  10. android开发百度地图LocationClient找不到 解决
  11. SD卡、SDHC卡和SDXC卡的功能及区别
  12. 在matlab下使用深度学习预训练模型Alex Net进行迁移学习的实验与分析
  13. 联通沃商店宣布独立运作 成立小沃科技公司
  14. 多看系统kindle最新版_谁说电气造价难?这样系统梳理一下简单多了!小白必看...
  15. C++ Qt 05:Qt布局管理器 - 荒 木 - 博客园
  16. 多传感器融合感知 --传感器外参标定及在线标定学习
  17. 初探GO中的反射机制
  18. 电信3g在小米信号显示无服务器,关于小米手机电信3G信号问题的分析
  19. 如何用vscode替代xshell
  20. Sharding-Sphere 的应用性能监控实践

热门文章

  1. web常见漏洞修复方法
  2. 《增长黑客》读书笔记
  3. BlackBerry不能上网问题解决方案
  4. android studio实现记住密码,Andriod Studio实现保存QQ密码功能(案例代码详解)
  5. 【你是如何应对杠精行为?】如此精彩语录,看完不笑算我输
  6. esp分区创建 linux_怎样向esp分区添加引导文件?
  7. 吴恩达深度学习工程师系列课程笔记(Deep Learning Specialization - deeplearning.ai)
  8. ffmpeg(六)视频缩放及像素格式转换
  9. 计算机网络之物理层,数据链路层,网络层 学习笔记
  10. 物联网应用开发实践案例-智能家居