动态规划之合唱队形问题(最长递增子序列变形)

2024-06-03 14:18

本文主要是介绍动态规划之合唱队形问题(最长递增子序列变形),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述 
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学不交换位置就能排成合唱队形。

合唱队形定义:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,

则他们的身高满足T1 < T2 < … < Ti, Ti > Ti+1 > … > TK (1 <= i <= K)。 
要求:已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入 
输入的第一行是一个整数N,表示同学的总数。 
第一行有n个整数,用空格分隔,第i个整数Ti是第i位同学的身高(厘米)。

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

解题思路 
定义n位同学的身高数组为a[n](注意这里数组长度不允许为变量,这里只是为了理解将n写如到[]中)。

总体思路】:假设第i(0<= i <= n - 1)个同学为最高点,分别求出此时i左边的最长递增子序列长度inc1[i],i右边的最长递减子序列长度inc2[i],由于最高点i同时包括在了inc1[i]和inc2[i]之中,因此实际的合唱队形的长度为inc1[i] + inc2[i] - 1。而我们求得的最后结果就是i从1到n - 1中,使得inc1[i] + inc2[i] - 1最大的情况。

具体实现】:现在设i为下标,循环i从0到n-1,求得各种i值对应的inc1[i];循环i从0到n-1,求得各种i值对应的inc2[i]。最后循环i从0到n-1,求得各种i值对应的inc[i] + inc2[i] - 1最大的情况ans,然后n - ans即为出列同学的人数。

当i = 0的时候,最高点0左边只有它自己,因此inc1[0] = 1;当i = n - 1的时候,最高点n - 1右边只有它自己,因此inc2[n - 1] = 1;当i处于0到n - 1之间时的求法也很好理解,在求inc1[i]时,j = (0 ~ i - 1)的inc[j]已经得出来了,所以我们只需要比较在前面的这些序列中加上a[i]时的最长递增序列,即在a[i]大于前面这些序列值的情况下inc[j] + 1最大的情况即为inc[i]。

源代码如下:

#include <iostream>
#include <stdio.h>
using namespace std;int inc1[200],inc2[200],a[200];
//inc1-->longest increase array from head to tail
//inc2-->longest increase array from tail to headint main()
{int n;while(scanf("%d",&n)!=EOF){int ans=0,i,j;for(i = 0; i < n; i++)  //输入n个人的身高scanf("%d",&a[i]);//inc1[i]是存储以i为最高点时左边的递增子序列长度inc1[0]=1;for(i = 1; i < n; i++){inc1[i] = 1;for(j = 0; j < i; j++)if(a[i] > a[j] && inc1[j] + 1 > inc1[i])inc1[i] = inc1[j]+1;}//inc2[i]是存储以i为最高点时左边的递减子序列长度inc2[n - 1] = 1;for(i = n - 2; i >= 0; i--){inc2[i] = 1;for(j = n - 1; j > i; j--)if(a[j] < a[i] && inc2[j] + 1 > inc2[i])inc2[i] = inc2[j] + 1;}for(i = 0; i<=n; i++)if(inc1[i] + inc2[i]-1 > ans) ans = inc1[i] + inc2[i] - 1;printf("%d\n",n-ans);}return 0;
}

这篇关于动态规划之合唱队形问题(最长递增子序列变形)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027219

相关文章

大数据小内存排序问题如何巧妙解决

《大数据小内存排序问题如何巧妙解决》文章介绍了大数据小内存排序的三种方法:数据库排序、分治法和位图法,数据库排序简单但速度慢,对设备要求高;分治法高效但实现复杂;位图法可读性差,但存储空间受限... 目录三种方法:方法概要数据库排序(http://www.chinasem.cn对数据库设备要求较高)分治法(常

SpringBoot实现动态插拔的AOP的完整案例

《SpringBoot实现动态插拔的AOP的完整案例》在现代软件开发中,面向切面编程(AOP)是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的AOP实现中,切... 目录引言一、AOP 概述1.1 什么是 AOP1.2 AOP 的典型应用场景1.3 为什么需要动态插

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

关于@MapperScan和@ComponentScan的使用问题

《关于@MapperScan和@ComponentScan的使用问题》文章介绍了在使用`@MapperScan`和`@ComponentScan`时可能会遇到的包扫描冲突问题,并提供了解决方法,同时,... 目录@MapperScan和@ComponentScan的使用问题报错如下原因解决办法课外拓展总结@

MybatisGenerator文件生成不出对应文件的问题

《MybatisGenerator文件生成不出对应文件的问题》本文介绍了使用MybatisGenerator生成文件时遇到的问题及解决方法,主要步骤包括检查目标表是否存在、是否能连接到数据库、配置生成... 目录MyBATisGenerator 文件生成不出对应文件先在项目结构里引入“targetProje

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1