动态规划经典问题大合集

合集下载

动态规划练习题(含答案)

动态规划练习题(含答案)

动态规划练习题USACO 2.2 Subset Sums题目如下:对于从1到N的连续整集合合,能划分成两个子集合,且保证每个集合的数字和是相等的。

举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字和是相等的:and {1,2}这是唯一一种分发(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)如果N=7,有四种方法能划分集合{1,2,3,4,5,6,7},每一种分发的子集合各数字和是相等的:{1,6,7} and {2,3,4,5} {注1+6+7=2+3+4+5}{2,5,7} and {1,3,4,6}{3,4,7} and {1,2,5,6}{1,2,4,7} and {3,5,6}给出N,你的程序应该输出划分方案总数,如果不存在这样的划分方案,则输出0。

程序不能预存结果直接输出。

PROGRAM NAME: subsetINPUT FORMAT输入文件只有一行,且只有一个整数NSAMPLE INPUT (file subset.in)7OUTPUT FORMAT输出划分方案总数,如果不存在则输出0。

SAMPLE OUTPUT (file subset.out)4参考程序如下:#include <fstream>using namespace std;const unsigned int MAX_SUM = 1024;int n;unsigned long long int dyn[MAX_SUM];ifstream fin ("subset.in");ofstream fout ("subset.out");int main() {fin >> n;fin.close();int s = n*(n+1);if (s % 4) {fout << 0 << endl;fout.close ();return ;}s /= 4;int i, j;dyn [0] = 1;for (i = 1; i <= n; i++)for (j = s; j >= i; j--)dyn[j] += dyn[j-i];fout << (dyn[s]/2) << endl;fout.close();return 0;}USACO 2.3 Longest Prefix题目如下:在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的。

动态规划-例题众多-详细讲解

动态规划-例题众多-详细讲解

步骤2:状态转移方程:
步骤3:以自底向上的方法来计算最优解
12
程序的实现
BuyTicks(T, R)
1 n ← length[T]
2 f[0] ← 0
3 f[1] ← T[1]
4 for i ← 2 to n do
5
f[i] ← f[i-2]+R[i-1]
6
if f[i] > f[i-1]+T[i] then
n 0 1 2 3 4 5 6 7 8 9 10 F(n) 1 1 2 3 5 8 13 21 34 55 89
2
递归 vs 动态规划
递归版本:
F(n)
1 if n=0 or n=1 then
2
return 1
3 else
4
return F(n-1) + F(n-2)
太慢!
动态规划:
F(n)
1 A[0] = A[1] ← 1
这里是某支股票的价格清单: 日期 1 2 3 4 5 6 7 8 9 10 11 12 价格 68 69 54 64 68 64 70 67 78 62 98 87 最优秀的投资者可以购买最多4次股票,可行方案中的一种是: 日期 2 5 6 10 价格 69 68 64 62 输入 第1行: N (1 <= N <= 5000),股票发行天数 第2行: N个数,是每天的股票价格。 输出 输出文件仅一行包含两个数:最大购买次数和拥有最大购买次数的方案数(<=231) 当二种方案“看起来一样”时(就是说它们构成的价格队列一样的时候),这2种方 案被认为是相同的。
你的任务是,已知所有N位同学的身高,计算最少需要 几位同学出列,可以使得剩下的同学排成合唱队形。

动态规划经典——最长公共子序列问题(LCS)和最长公共子串问题

动态规划经典——最长公共子序列问题(LCS)和最长公共子串问题

动态规划经典——最长公共⼦序列问题(LCS)和最长公共⼦串问题⼀.最长公共⼦序列问题(LCS问题)给定两个字符串A和B,长度分别为m和n,要求找出它们最长的公共⼦序列,并返回其长度。

例如: A = "Hel lo W o rld" B = "loo p"则A与B的最长公共⼦序列为 "loo",返回的长度为3。

此处只给出动态规划的解法:定义⼦问题dp[i][j]为字符串A的第⼀个字符到第 i 个字符串和字符串B 的第⼀个字符到第 j 个字符的最长公共⼦序列,如A为“app”,B为“apple”,dp[2][3]表⽰ “ap” 和 “app” 的最长公共字串。

注意到代码中 dp 的⼤⼩为 (n + 1) x (m + 1) ,这多出来的⼀⾏和⼀列是第 0 ⾏和第 0 列,初始化为 0,表⽰空字符串和另⼀字符串的⼦串的最长公共⼦序列,例如dp[0][3]表⽰ "" 和“app” 的最长公共⼦串。

当我们要求dp[i][j],我们要先判断A的第i个元素B的第j个元素是否相同即判断A[i - 1]和 B[j -1]是否相同,如果相同它就是dp[i-1][j-1]+ 1,相当于在两个字符串都去掉⼀个字符时的最长公共⼦序列再加 1;否则最长公共⼦序列取dp[i][j - 1] 和dp[i - 1][j]中⼤者。

所以整个问题的初始状态为:dp[i][0]=0,dp[0][j]=0相应的状态转移⽅程为:dp[i][j]=max{dp[i−1][j],dp[i][j−1]},A[i−1]!=B[j−1] dp[i−1][j−1]+1,A[i−1]==B[j−1]代码的实现如下:class LCS{public:int findLCS(string A, int n, string B, int m){if(n == 0 || m == 0)//特殊输⼊return 0;int dp[n + 1][m + 1];//定义状态数组for(int i = 0 ; i <= n; i++)//初始状态dp[i][0] = 0;for(int i = 0; i <= m; i++)dp[0][i] = 0;for(int i = 1; i <= n; i++)for(int j = 1; j<= m; j++){if(A[i - 1] == B[j - 1])//判断A的第i个字符和B的第j个字符是否相同dp[i][j] = dp[i -1][j - 1] + 1;elsedp[i][j] = max(dp[i - 1][j],dp[i][j - 1]);}return dp[n][m];//最终的返回结果就是dp[n][m]}};该算法的时间复杂度为O(n*m),空间复杂度为O(n*m)。

动态规划问题常见解法

动态规划问题常见解法

动态规划问题常见解法
动态规划是一种高效解决优化问题的方法。

它通常用于涉及最
优化问题和最短路径的计算中。

下面是一些常见的动态规划问题解法:
1. 背包问题
背包问题是动态规划中的经典问题之一。

其目标是在给定的背
包容量下,选择一些物品放入背包中,使得物品总价值最大。

解决
这个问题的常见方法是使用动态规划的思想,定义一个二维数组来
记录每个物品放入背包时的最大价值,然后逐步计算出最终的结果。

2. 最长公共子序列问题
最长公共子序列问题是寻找两个字符串中最长的公共子序列的
问题。

解决这个问题的常见方法是使用动态规划的思想,定义一个
二维数组来记录两个字符串中每个位置的最长公共子序列的长度。

然后通过递推关系来计算出最终的结果。

3. 矩阵链乘法问题
矩阵链乘法问题是计算一系列矩阵相乘的最佳顺序的问题。


决这个问题的常见方法是使用动态规划的思想,定义一个二维数组
来记录每个矩阵相乘时的最小乘法次数,然后逐步计算出最终的结果。

4. 最长递增子序列问题
最长递增子序列问题是寻找一个序列中最长的递增子序列的问题。

解决这个问题的常见方法是使用动态规划的思想,定义一个一
维数组来记录每个位置处的最长递增子序列的长度,然后通过递推
关系来计算出最终的结果。

以上是一些常见的动态规划问题解法。

通过灵活运用这些方法,我们可以更高效地解决优化问题和最短路径计算等相关任务。

动态规划试题

动态规划试题

1. 某公司打算向它的三个营业区增设6个销售店,每个营业区至少增设1个。

各营业区每年增加的利润与增设的销售店个数有关,具体关系如表1所示。

试规划各营业区应增设销售店的个数,以使公司总利润增加额最大。

表1解:将问题按区分为三个阶段3,2,1=k ,设状态变量k S (3,2,1=k )代表从第k 个区到第3个区的增设个数,决策变量k x 代表第k 个区的增设个数。

于是有状态转移率k k k x S S -=+1、允许决策集合}0|{)(k k k k k S x x S D ≤≤=和递推关系式:)}()({max )(10k k k k k S x k k x S f x g S f kk -+=+≤≤ )1,2,3(=k0)(44=S f当3=k 时:)}({max }0)({max )(330330333333x g x g S f S x S x ≤≤≤≤=+=于是有表7-2,表中*3x 表示第三个阶段的最优决策。

单位:百万元当2=k 时:)}()({max )(2232202222x S f x g S f S x -+=≤≤于是有表7-3。

表7-3 (单位:百万元)当1=k 时:)}()({max )(1121101111x S f x g S f S x -+=≤≤于是有表7-4。

故最优分配方案为:A 区建3个销售店,B 区建2个销售店,C 区建1个销售店, 总利润为490万元。

2. 某工厂有100台机器,拟分4个周期使用,在每一周期有两种生产任务,据经验把机器投入第一种生产任务,则在一个周期中将有六分之一的机器报废,投入第二种生产任务,则有十分之一的机器报废。

如果投入第一种生产任务每台机器可收益1万元,投入第二种生产任务每台机器可收益0.5万元。

问怎样分配机器在4个周期内的使用才能使总收益最大? 解:阶段:将每个周期作为一个阶段,即k=1,2,3,4 状态变量:第k 阶段的状态变量k S 代表第k 个周期初拥有的完好机器数决策变量:决策变量k x 为第k 周期分配与第一种任务的机器数量,于是k k x S -该周期分配在第二种任务的机器数量。

NOI导刊资源背包动态规划

NOI导刊资源背包动态规划
给定N枚硬币 给定T元钱 用这N枚硬币找这T元钱,使得剩下的钱最
少。
剩下钱数最少的找零方案中的所需的最少 硬币数。
N<=500,T<=10000.
分析
设F[i]表示需要找的钱数为i时所需要的最少 钱币数。显然有:
F[i]=Min{F[ i - A[j] ] + 1} { i≤ T,1≤j≤N} 初始值:F[0]=0。 A[j]表示其中 第j种钱币的面值。 时间复杂度为O(N*T)。
动态规划
• 可以按每个物品进行规划,同样每种物品有选和 不选两种选择
• 设F(i,j)表示前i件物品载重为j的最大效益,则有
F(i 1, j w[i]) C[i],第i种物品装载 F(i, j) MaxF(i 1, j),第i种物品不装载
• 1<=i<=N, 0<=j<=N • 初值:F(0,j)=0 • F(N,M)即答案 • 显然时间复杂度为O(NM)
for j:=0 to m do
begin

if j>=w[i] then //背包容量够大
f[j]:=max(f[j-w[i]]+c[i],f[j])
end;
思考题1:机器分配
• M台设备,分给N个公司。 • 若公司i获得j台设备,则能产生Aij效益 • 问如何分配设备使得总效益最大? • M<=15,N<=10。
else
//背包容量不足
f[i,j]:=f[i-1,j];
end;
满背包问题(01背包)
• 有N件物品; • 第i件物品Wi公斤; • 第i件物品价值Ci元; • 现有一辆载重M公斤的卡车; • 问选取装载哪些物品,使得卡车开车正
好装满时,运送的总价值最大? 若无法装满卡车,则输出无解。

动态规划总结经典题目(经典中的经典)

动态规划总结经典题目(经典中的经典)

动态规划总结——经典问题总结本文着重讨论状态是如何表示,以及方程是怎样表示的。

当然,还附上关键的,有可能作为模板的代码段。

但有的代码的实现是优化版的。

经典问题总结最长上升子序列(LIS)问题描述如下:设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。

求最大的m值。

这里采用的是逆向思维的方法,从最后一个开始想起,即先从A[N](A数组是存放数据的数组,下同)开始,则只有长度为1的子序列,到A[N-1]时就有两种情况,如果a[n-1] < a[n] 则存在长度为2的不下降子序列a[n-1],a[n];如果a[n-1] > a[n] 则存在长度为1的不下降子序列a[n-1]或者a[n]。

有了以上的思想,DP方程就呼之欲出了(这里是顺序推的,不是逆序的):DP[I]=MAX(1,DP[J]+1)J=0,1,...,I-1但这样的想法实现起来是)O(n^2)的。

本题还有更好的解法,就是O(n*logn)。

利用了长升子序列的性质来优化,以下是优化版的代码://最长不降子序const int SIZE=500001;int data[SIZE];int dp[SIZE];//返回值是最长不降子序列的最大长度,复杂度O(N*logN)int LCS(int n) { //N是DATA数组的长度,下标从1开始int len(1),low,high,mid,i;dp[1]=data[1];for(i=1;i<=n;++i) {low=1;high=len;while( low<=high ) { //二分mid=(low+high)/2;if( data[i]>dp[mid] ) {low=mid+1;}else {high=mid-1;}}dp[low]=data[i];if( low>len ) {++len;}}return len;}最长公共子序列(LCS)给出两个字符串a, b,求它们的最长、连续的公共字串。

动态规划习题

动态规划习题

动态规划专题分类视图数轴动规题: (1)较复杂的数轴动规 (4)线性动规 (7)区域动规: (14)未知的动规: (20)数轴动规题:题1.2001年普及组第4题--装箱问题【问题描述】有一个箱子容量为V(正整数,0≤V≤20000),同时有n个物品(0<n≤30),每个物品有一个体积(正整数)。

要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

【输入格式】输入文件box.in有若干行。

第一行:一个整数,表示箱子容量V;第二行:一个整数,表示物品个数n;接下来n行,分别表示这n个物品的各自体积。

【输出格式】输出文件box.out只有一行数据,该行只有一个数,表示最小的箱子剩余空间。

【输入样例】2468312797【输出样例】题2.1996年提高组第4题--砝码秤重__数据加强版【问题描述】设有n种砝码,第k种砝码有C k个,每个重量均为W k,求:用这些砝码能秤出的不同重量的个数,但不包括一个砝码也不用的情况。

【输入格式】输入文件weight.in的第一行只有一个数n,表示不同的砝码的种类数.第2行至第n+1行,每行有两个整数.第k+1行的两个数分别表示第k种砝码的个数和重量.【输出格式】输出文件weight.out中只有一行数据:Total=N。

表示用这些砝码能秤出的不同重量数。

【输入样例】22 22 3【输出样例】Total=8【样例说明】重量2,3,4,5,6,7,8,10都能秤得【数据限制】对于100%的数据,砝码的种类n满足:1≤n≤100;对于30%的数据,砝码的总数量C满足:1≤C≤20;对于100%的数据,砝码的总数量C满足:1≤C≤100;对于所有的数据,砝码的总重量W满足:1≤W≤400000;题3.石子归并-szgb.pas【问题描述】有一堆石头质量分别为W1,W2,…,Wn.(Wi≤10000),将石头合并为两堆,使两堆质量的差最小。

【输入】输入文件szgb.in的第一行只有一个整数n(1≤n≤50),表示有n堆石子。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态规划经典教程引言:本人在做过一些题目后对DP有些感想,就写了这个总结:第一节动态规划基本概念一,动态规划三要素:阶段,状态,决策。

他们的概念到处都是,我就不多说了,我只说说我对他们的理解:如果把动态规划的求解过程看成一个工厂的生产线,阶段就是生产某个商品的不同的环节,状态就是工件当前的形态,决策就是对工件的操作。

显然不同阶段是对产品的一个前面各个状态的小结,有一个个的小结构成了最终的整个生产线。

每个状态间又有关联(下一个状态是由上一个状态做了某个决策后产生的)。

下面举个例子:要生产一批雪糕,在这个过程中要分好多环节:购买牛奶,对牛奶提纯处理,放入工厂加工,加工后的商品要包装,包装后就去销售……,这样每个环节就可以看做是一个阶段;产品在不同的时候有不同的状态,刚开始时只是白白的牛奶,进入生产后做成了各种造型,从冷冻库拿出来后就变成雪糕(由液态变成固态)。

每个形态就是一个状态,那从液态变成固态经过了冰冻这一操作,这个操作就是一个决策。

一个状态经过一个决策变成了另外一个状态,这个过程就是状态转移,用来描述状态转移的方程就是状态转移方程。

经过这个例子相信大家对动态规划有所了解了吧。

下面再说说我对动态规划的另外一个理解:用图论知识理解动态规划:把动态规划中的状态抽象成一个点,在有直接关联的状态间连一条有向边,状态转移的代价就是边上的权。

这样就形成了一个有向无环图AOE网(为什么无环呢?往下看)。

对这个图进行拓扑排序,删除一个边后同时出现入度为0的状态在同一阶段。

这样对图求最优路径就是动态规划问题的求解。

二,动态规划的适用范围动态规划用于解决多阶段决策最优化问题,但是不是所有的最优化问题都可以用动态规划解答呢?一般在题目中出现求最优解的问题就要考虑动态规划了,但是否可以用还要满足两个条件:最优子结构(最优化原理)无后效性最优化原理在下面的最短路径问题中有详细的解答;什么是无后效性呢?就是说在状态i求解时用到状态j而状态j求解又用到状态k…..状态N。

而求状态N时又用到了状态i这样求解状态的过程形成了环就没法用动态规划解答了,这也是上面用图论理解动态规划中形成的图无环的原因。

也就是说当前状态是前面状态的完美总结,现在与过去无关。

当然,要是换一个划分状态或阶段的方法就满足无后效性了,这样的问题仍然可以用动态规划解。

三,动态规划解决问题的一般思路。

拿到多阶段决策最优化问题后,第一步要判断这个问题是否可以用动态规划解决,如果不能就要考虑搜索或贪心了。

当确定问题可以用动态规划后,就要用下面介绍的方法解决问题了:(1)模型匹配法:最先考虑的就是这个方法了。

挖掘问题的本质,如果发现问题是自己熟悉的某个基本的模型,就直接套用,但要小心其中的一些小的变动,现在考题办都是基本模型的变形套用时要小心条件,三思而后行。

这些基本模型在后面的分类中将一一介绍。

(2)三要素法仔细分析问题尝试着确定动态规划的三要素,不同问题的确定方向不同:先确定阶段的问题:数塔问题,和走路问题(详见解题报告)先确定状态的问题:大多数都是先确定状态的。

先确定决策的问题:背包问题。

(详见解题报告)一般都是先从比较明显的地方入手,至于怎么知道哪个明显就是经验问题了,多做题就会发现。

(3)寻找规律法:这个方法很简单,耐心推几组数据后,看他们的规律,总结规律间的共性,有点贪心的意思。

(4)边界条件法找到问题的边界条件,然后考虑边界条件与它的领接状态之间的关系。

这个方法也很起效。

(5)放宽约束和增加约束这个思想是在陈启锋的论文里看到的,具体内容就是给问题增加一些条件或删除一些条件使问题变的清晰。

第二节动态规划分类讨论这里用状态维数对动态规划进行了分类:1.状态是一维的1.1下降/非降子序列问题:问题描述:{挖掘题目的本质,一但抽象成这样的描述就可以用这个方法解}在一个无序的序列a1,a2,a3,a4…an里,找到一个最长的序列满足:ai<=aj<=ak…<=am,且i<j<k…<m.(最长非降子序列)或ai>aj>ak…>am,且i>j>k…>m.(最长下降子序列)。

问题分析:如果前i-1个数中用到ak (ak>ai或ak<=ai)构成了一个最长的序列加上第i个数ai就是前i个数中用到i的最长的序列了。

那么求用到ak构成的最长的序列有要求前k-1个数中……从上面的分析可以看出这样划分问题满足最优子结构,那满足无后效性么?显然对于第i个数时只考虑前i-1个数,显然满足无后效性,可以用动态规划解。

分析到这里动态规划的三要素就不难得出了:如果按照序列编号划分阶段,设计一个状态opt[i] 表示前i个数中用到第i个数所构成的最优解。

那么决策就是在前i-1个状态中找到最大的opt[j]使得aj>ai(或aj<=ai),opt[j]+1就是opt[i]的值;用方程表示为:{我习惯了这种写法,但不是状态转移方程的标准写法 } opt[i]=max(opt[j])+1 (0<=j<i 且aj<=ai) {最长非降子序列}opt[i]=max(opt[j])+1 (0<=j<i 且aj>ai) {最长下降子序列}实现求解的部分代码:opt[0]:=maxsize;{maxsize 为maxlongint或-maxlongint}for i:=1 to n dofor j:=0 to i-1 doif ( a[j]>a[i]) and (opt[j]+1>opt[i]) thenopt[i]:=opt[j]+1;ans:=-maxlongint;for i:=1 to n doif opt[i]>ans then ans:=opt[i]; {ans 为最终解}复杂度:从上面的实现不难看出时间复杂度为O(N2),空间复杂度O(N);例题1 拦截导弹(missile.pas/c/cpp) 来源:NOIP1999(提高组) 第一题【问题描述】某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。

但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。

某天,雷达捕捉到敌国的导弹来袭。

由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

【输入文件】missile.in单独一行列出导弹依次飞来的高度。

【输出文件】missile.out两行,分别是最多能拦截的导弹数,要拦截所有导弹最少要配备的系统数【输入样例】389 207 155 300 299 170 158 65【输出样例】62【提交链接】/Problem_217.html【问题分析】有经验的选手不难看出这是一个求最长非升子序列问题,显然标准算法是动态规划。

以导弹依次飞来的顺序为阶段,设计状态opt[i]表示前i个导弹中拦截了导弹i可以拦截最多能拦截到的导弹的个数。

状态转移方程:opt[i]=max(opt[j])+1 (h[i]>=h[j],0=<j<i) {h[i]存,第i个导弹的高度}最大的opt[i]就是最终的解。

这只解决了第一问,对于第二问最直观的方法就是求完一次opt[i]后把刚才要打的导弹去掉,再求一次opt[i]直到打完所有的导弹,但这样做就错了。

不难举出反例: 6 1 7 3 2错解: 6 3 2/1/7 正解:6 1/7 3 2其实认真分析一下题就会发现:每一个导弹最终的结果都是要被打的,如果它后面有一个比它高的导弹,那打它的这个装置无论如何也不能打那个导弹了,经过这么一分析,这个问题便抽象成在已知序列里找最长上升子序列的问题。

求最长上升序列和上面说的求最长非升序列是一样的,这里就不多说了。

复杂度:时间复杂度为O(N2),空间复杂度为O(N)。

【源代码】program missile;constfin='missile.in';fout='missile.out';maxn=10000;vara,opt:array[0..maxn] of longint;n,anslen,anstime:longint;procedure init;varx:longint;beginassign(input,fin);reset(input);assign(output,fout);rewrite(output);n:=0;repeatinc(n);read(a[n]); until seekeof;end;procedure main;vari,j:longint;beginfillchar(opt,sizeof(opt),0);a[0]:=maxlongint;for i:=1 to n dofor j:=i-1 downto 0 doif (a[j]>=a[i]) and(opt[j]+1>opt[i]) thenopt[i]:=opt[j]+1;anslen:=0;for i:=1 to n doif opt[i]>anslen thenanslen:=opt[i];fillchar(opt,sizeof(opt),0);a[0]:=-maxlongint;for i:=1 to n dofor j:=i-1 downto 0 doif (a[j]<a[i]) and (opt[j]+1>opt[i]) thenopt[i]:=opt[j]+1;anstime:=0;for i:=1 to n doif opt[i]>anstime thenanstime:=opt[i];end;procedure print;beginwriteln(anslen);writeln(anstime);close(input);close(output);end;begininit;main;print;end.例题2 合唱队形(chorus.pas/c/cpp) 来源:NOIP2004(提高组) 第一题N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。

合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,则他们的身高满足T1<...<Ti>Ti+1>…>TK(1<=i<=K)。

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

相关文档
最新文档