最长上升子序列——蒜头君的娃娃

蒜头君十分喜爱它的娃娃,经常会把它们摆成一列。蒜头君从左到右依次给他们编号为 11 到 NN,每个娃娃都有自己的萌值 T_iT?i??。现在蒜头君想从已经摆好的队列中,去除几个娃娃,使得剩余的队列满足以下条件:

\displaystyle T_1 < ... < T_i > T_{i+1} > ... > T_K (1 \leq i \leq K)T?1??<...<T?i??>T?i+1??>...>T?K??(1≤i≤K)

现在已知队列中 NN 个娃娃的萌值,请你帮蒜头君计算一下,最少需要去除多少个娃娃才能满足上面的条件。

输入格式

输入两行。输入第一行是一个整数 N(2 \leq N \leq 100)N(2≤N≤100),表示娃娃的总数。第二行输入 NN 个整数,每两个整数之间用一个空格隔开,第 ii 个整数 T_i(130 \leq T_i \leq 230)T?i??(130≤T?i??≤230) 是第 ii 个娃娃的萌值。

输出格式

输出一行,输出一个整数,表示最少去除娃娃的个数。

样例输入

6
184 163 210 166 170 155

样例输出

2

分析:正向dp一次,反向dp一次,然后取两次dp值的和中最大的那个。答案即为娃娃的总数减去最大和值+1。O(n^2)算法

AC代码

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int n;//娃娃总数
 5 int a[105];//存储娃娃萌值
 6 int dp1[105];//存储正向dp结果
 7 int dp2[105];//存储反向dp结果
 8 void DP1()//正向dp
 9 {
10     for(int i=1;i<=n;i++)
11         for(int j=1;j<i;j++)
12     {
13         if(a[i]>a[j])
14             dp1[i]=max(dp1[i],dp1[j]+1);
15     }
16
17 }
18 void DP2()//反向dp
19 {
20     for(int i=n;i>=1;i--)
21         for(int j=n;j>i;j--)
22     {
23         if(a[i]>a[j])
24             dp2[i]=max(dp2[i],dp2[j]+1);
25     }
26
27 }
28 int get_ans()
29 {
30     int ans=0;
31     for(int i=1;i<=n;i++)
32     {
33         ans=max(ans,dp1[i]+dp2[i]);
34     }
35     return ans;
36 }
37 int main()
38 {
39     scanf("%d",&n);
40     for(int i=1;i<=n;i++)
41     {
42         scanf("%d",&a[i]);
43         dp1[i]=1;
44         dp2[i]=1;
45     }
46     DP1();
47     DP2();
48     int ans=get_ans();
49     printf("%d\n",n-ans+1);
50     return 0;
51 }

 
时间: 2024-12-16 17:40:16

最长上升子序列——蒜头君的娃娃的相关文章

动态规划|蒜头君跳木桩-最长下降子序列

蒜头君跳木桩 蒜头君面前有一排?nn?个木桩,木桩的高度分别是h_1,h_2,h_3\cdots h_nh1?,h2?,h3??hn?.蒜头第一步可以跳到任意一个木桩,接下来的每一步蒜头不能往回跳只能往前跳,并且跳下一个木桩的高度?不大于?当前木桩.蒜头君希望能踩到尽量多的木桩,请你帮蒜头计算,最多能踩到多少个木桩. 输入格式 第一行输入一个整数?nn?代表木桩个数.第二行输入?nn?个整数?h_1,h_2,h_3\cdots h_nh1?,h2?,h3??hn?,分别代表?nn?个木桩的高度.

蒜头君的日志(最长公共上升子序列)

蒜头君喜欢把做过的事情记录下来,写在日志里,为了安全起见,它还有一份备份放在另外的地方,不过很不幸的是,最近他的两份日志都受到了破坏,有增加删除修改,但没有改变任何原来的顺序,两份受到的破坏不一定一样,蒜头君记录事情都是按时间顺序的,记录的也都是时间戳,所以正确的记录上时间戳肯定是严格递增的,并且只有两份记录上都出现了的时间戳他才认为有可能自己做了,现在他想知道他最多可能做了多少事情. 输入格式 第一行输入两个整数n,m代表两份记录的长度.(1≤n,m≤103) 接下来一行输入n个整数,a1,a

RMQ——蒜头君的玩具娃娃(区间范围最大值-区间范围最小值)

蒜头君有 N 个玩具娃娃,编号依次从 1 到 N,每个娃娃都有自己的高度值.蒜头君想考考聪明的你,蒜头君会有 Q 次询问,每次询问给定两个整数 A 和 B,求问编号 A 和编号 B 之间(包含编号 A 和编号 B),高度最大的娃娃和高度最小的娃娃差是多少. 输入格式 第一行输入两个正整数 N,Q(N≤50,000,Q≤200,000).代表 N 个玩具娃娃,以及蒜头君的 Q 次 询问. 接下来输入 N 行,每行输入一个正整数 h?i??(1≤h?i??≤1,000,000),表示第i 个玩具的高

回文串(最长公共子序列)

一个字符串如果从左往右读和从右往左读都一样,那么这个字符串是一个回文串.例如:"abcba","abccba". 蒜头君想通过添加字符把一个非回文字符串变成回文串.例如:"trit",可以添加一个i变成回文串"tirit". 请你用程序计算出,对于一个给定的字符串,最少需要添加几个字符,才能变成回文串. 输入格式 输入一个长度为n(1≤n≤3000)的字符串.(字符串只包含字母) 输出格式 输出最少需要添加的字符个数,占一行.

蒜头君救人

蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境,假设蒜头君所在的村子是 n \times mn×m 的网格,网格中.号代表平地,#号代表该地已被洪水淹没,A.B--等大写字母表示该地有村民被困,s代表蒜头君的起点,t代表蒜头君的终点. 蒜头君的初始速度为 kk 秒一格,他每次可以向上下左右 44 个方向中的一个移动 11 格.在背上一个村民后,他的速度可能会降低,也可能会加快,但他的速度不能快于 11 秒每格,那么蒜头君想知道,他

LCS修改版(Longest Common Subsequence 最长公共子序列)

题目描述 作为一名情报局特工,Nova君(2号)有着特殊的传达情报的技巧.为了避免被窃取情报,每次传达时,他都会发出两句旁人看来意义不明话,实际上暗号已经暗含其中.解密的方法很简单,分别从两句话里删掉任意多个字母,使得两句话剩余的部分相同,通过一定的删除手法,可以让剩余的部分相同且长度最大,就得到了可能的暗号.暗号可能有多个,还要进行筛选,现在情报局人手不够,希望你能助一臂之力,筛选工作不用你完成,你只需计算出暗号长度以及个数即可.(注意,字母的位置也是暗号的重要信息,位置不同的字母组成的暗号不

动态规划算法解最长公共子序列LCS问题

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们

【基础练习】【线性DP】codevs1408 最长公共子序列(上升)题解

</pre><p></p><p style="color:rgb(54,46,43); font-family:Arial; font-size:14px; line-height:26px"><span style="line-height:24px; text-indent:28px">这道题目捣鼓了一个小时了终于弄出来咯···怒吼三声:容易吗!文章被盗还是很严重,加版权信息转载请注明出处 [ameta

14-高效求最长公共子序列(二维数组存不下)

/*                                   See LCS again时间限制:1000 ms  |  内存限制:65535 KB难度:3 描述 There are A, B two sequences, the number of elements in the sequence is n.m; Each element in the sequence are different and less than 100000. Calculate the length