day19 482 合唱队形 (线性DP)
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)表示了三种情况。
i = 1
,TiT_iTi就是第一个数,故这是一个完全递减
序列。i = k
,TiT_iTi就是最后一个数,故这是一个完全递增
序列。i
在1~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)相关推荐
- P1091 合唱队形[单调性+DP]
题目来源:洛谷 题目描述 N位同学站成一排,音乐老师要请其中的(N−K)位同学出列,使得剩下的K位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,-,K,他们的身高 ...
- 【OpenJ_Bailian - 2711 】 合唱队形(dp,枚举中间顶点)
题干: N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, -, K,他们的 ...
- 【动态规划刷题笔记】线性dp:合唱队形(最长递增子序列的变体)
[NOIP2004 提高组] 合唱队形 - 洛谷 思路:最少出列,即挑出最多,即找最长递增子序列和最长递减子序列 设dp1[i]为以h[i]结尾的最长递增子序列 dp2[i]为以h[i]开头的最长递减 ...
- UOJ #214 合唱队形 (概率期望计数、DP、Min-Max容斥)
UOJ #214 合唱队形 (概率期望计数.DP.Min-Max容斥) 9个月的心头大恨终于切掉了!!!! 非常好的一道题,不知为何uoj上被点了70个差评. 题目链接: http://uoj.ac/ ...
- tyvj 1067 合唱队形 dp LIS
P1067 合唱队形 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2004 提高组 第三道 描述 N位同学站成一排,音乐老师要请其中的(N-K)位 ...
- 【DP】合唱队形(jzoj 1122)
合唱队形 jzoj 1122 题目大意: 有n个人,按一定的顺序站成一排,最少减去多少个人可以使队列以一个人为中心,两边分别递减 输入样例 8 186 186 150 200 160 130 197 ...
- 动态规划 —— 线性 DP
[概述] 线性动态规划,是较常见的一类动态规划问题,其是在线性结构上进行状态转移,这类问题不像背包问题.区间DP等有固定的模板. 线性动态规划的目标函数为特定变量的线性函数,约束是这些变量的线性不等式 ...
- 合唱队形(递增再递减的最长子序列)
题目描述 N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, -, K,他们的 ...
- P1091 合唱队形(LIS)
题目描述 NNN位同学站成一排,音乐老师要请其中的(N−KN-KN−K)位同学出列,使得剩下的KKK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,-,K1,2, ...
- LuoGU 线性DP
P1091 合唱队形 看一下题解吧,你好i需要正反搜一下lcs ,然后合并 #include<bits/stdc++.h> using namespace std; #define LOA ...
最新文章
- web developer tips (39):在Visual Studio 2008中取消远程web操作
- 《漫画算法2》源码整理-1 二分查找树 AVL树 红黑树
- 九、“行胜于言车胜马,负重致远向前途”
- catkin_make与gtest出现冲突的问题与解决
- USACO-Section1.3 Transformations (矩阵旋转匹配问题)
- LVS NAT 模型配置实例
- 设计师需要的素材网站,给你归纳好了,拿走!
- Debug调试工具使用
- 2021费控报销领域最具商业合作价值企业盘点
- android开发百度地图LocationClient找不到 解决
- SD卡、SDHC卡和SDXC卡的功能及区别
- 在matlab下使用深度学习预训练模型Alex Net进行迁移学习的实验与分析
- 联通沃商店宣布独立运作 成立小沃科技公司
- 多看系统kindle最新版_谁说电气造价难?这样系统梳理一下简单多了!小白必看...
- C++ Qt 05:Qt布局管理器 - 荒 木 - 博客园
- 多传感器融合感知 --传感器外参标定及在线标定学习
- 初探GO中的反射机制
- 电信3g在小米信号显示无服务器,关于小米手机电信3G信号问题的分析
- 如何用vscode替代xshell
- Sharding-Sphere 的应用性能监控实践
热门文章
- web常见漏洞修复方法
- 《增长黑客》读书笔记
- BlackBerry不能上网问题解决方案
- android studio实现记住密码,Andriod Studio实现保存QQ密码功能(案例代码详解)
- 【你是如何应对杠精行为?】如此精彩语录,看完不笑算我输
- esp分区创建 linux_怎样向esp分区添加引导文件?
- 吴恩达深度学习工程师系列课程笔记(Deep Learning Specialization - deeplearning.ai)
- ffmpeg(六)视频缩放及像素格式转换
- 计算机网络之物理层,数据链路层,网络层 学习笔记
- 物联网应用开发实践案例-智能家居