hdu2198 How many elements you must throw out? C语言动态规划题

原题链接http://acm.hdu.edu.cn/showproblem.php?pid=2198

Problem Description
You have a sequence of numbers from which you must create the longest subsequence satisfying the following condition: it can be ‘cut’ into two parts that share exactly one common element (the last element of the first part is the first element of the second part), and the first part is sorted in strictly ascending order while the second part is sorted in strictly descending order. For example, the sequence { 1, 4, 6, 5, 2, 1 } can be ‘cut’ into { 1, 4, 6 } and { 6, 5, 2, 1 }. The two parts share the 6(see the following graph), and the first sequence is sorted in ascending order while the second sequence is sorted in descending order.


You are given a sequence of numbers. Output the minimal number of elements you must throw out from the given sequence such that the remaining subsequence satisfies the condition described above.

Input
There are multiple test cases. At first line of each case, there’s an integer N (1<=N<=50) and N integers followed at second line representing the subsequence, each of which ranges from 1 to 1000000000.Input ends when N is 0.

Output
Output the result for each case in one line.

Sample Input
6
1 4 6 5 2 1
5
2 2 2 2 2
0

Sample Output
0
4

题目意思
上面所说的大概就是一段连续数列中你要找出一个数,将这个数列从这个数分成两部分,然后前一个数列末尾数据是这个数,后一个数列开头是这个数。然后要满足前一个数列是递增的,后一个数列是递减的,如果不存在则删去某几个数使得这两个数列存在。求最少要删去几个数。

读懂题目其实很简单,其实就是求在某个数将该数列分成两个数列后,前一段数列的最长递增子序列(非连续)和后一段数列的最长递减子序列(非连续)的长度之和的最大值。

比如1 4 6 5 2 1,当选定数据6时候,分成 1 4 6和6 5 2 1两组数据,这时候他们的最长子序列分别是1 4 6和6 5 2 1,这时候就输出6(原先数列长度)+1(有一个数据重复)-3(前一段递增子序列长度)-4(后一段递减子序列长度)=0。
又比如5 4 3 2 1 2 3 4 5。将它分成九种不同的两段数列。当数据为第一个5(或者最后一个5)时,分成两个子数列分别为5以及
5 4 3 2 1 2 3 4 5。这时候前一个最长子序列是2(本身),长度为1,后一个最长子序列是5 4 3 2 1,长度为5。
输出结果就是9+1-1-5=4。

由于数据数量比较少(我自己很菜也不知道除了这个办法有什么办法),将数列中每一个数遍历,然后求如果当前这个数是分割数的时候,两个数列里递增(递减)最长子序列长度之和,然后与求得的相比较求出最大值。

代码如下

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;double a[55],b[55],dp1[55],dp2[55];int main()
{int n;while(scanf("%d",&n)!=EOF&&n){int mx=0;for(int i=0;i<n;i++)scanf("%lf",&a[i]);int pos;// 用于记录当前分割位置for(int k=0;k<n;k++){pos=k;int f=0;for(int i=n-1;i>=pos;i--){b[f++]=a[i];  //将后半部分求递减数列部分逆置变为求递增数列便于理解}for(int i=0;i<=50;i++)dp1[i]=1;   //将dp数组内元素初始化为1,因为如果前面没有元素满足比它小(大)时,它本身算为一个长度int MAX1=1; //记录前一段数列中最长递增子序列的长度for(int i=0;i<=pos;i++){for(int j=0;j<i;j++){if(a[i]>a[j]){dp1[i]=max(dp1[i],dp1[j]+1);
//dp1[j]代表到j位置的数时最长的子序列长度,如果a[i]比a[j]长,那么此时dp[i]的最长子序列长度为dp[j]+1或者位置j之前更长的子序列if(dp1[i]>MAX1)MAX1=dp1[i];}}} for(int i=0;i<=50;i++)dp2[i]=1;int MAX2=1;for(int i=0;i<f;i++){for(int j=0;j<i;j++){if(b[i]>b[j]){dp2[i]=max(dp2[i],dp2[j]+1);   //同上if(dp2[i]>MAX2) MAX2=dp2[i];}}}if(MAX1+MAX2>mx)mx=MAX1+MAX2;       //记录下最长的两部分子序列长度和}printf("%d\n",n+1-mx);  //由于有重复部分故需+1}return 0;
}

by有点弱智的鲤鱼王

hdu2198 How many elements you must throw out? C语言动态规划题相关推荐

  1. uva10534 hdu2198 双向LIS问题

    LIS问题算是DP中很基础很简单的一类问题,其经典算法时间复杂度为O(n^2):利用它本身的特点,结合二分法,即可设计出时间复杂度为O(n*log n)的优化算法.LIS的变形好像不太多,下面是两个很 ...

  2. 6、语句(if、switch、for、while、for...in/of、do-while、break、continue、label、return、throw、try-catch-finally、w

    目录 语句 一. if语句 1. if 语句 2. if...else 语句 3.if...else if....else 语句 二. switch语句 三. for语句 四. while语句 五. ...

  3. Java数据结构与算法(一) 数组

    ###1. 无序数组 package com.fantj.dataStruct.array;/*** Created by Fant.J.* 2017/12/20 18:16*/ public cla ...

  4. 微软等数据结构+算法面试100题全部答案集锦

    微软等数据结构+算法面试100题全部答案集锦 作者:July.阿财. 时间:二零一一年十月十三日. 引言 无私分享造就开源的辉煌. 今是二零一一年十月十三日,明日14日即是本人刚好开博一周年.在一周年 ...

  5. java 队列的数组_JAVA-循环数组实现简单的队列

    public class CircularArrayQueue { private int[] elements; private int head; private int tail; //初始化队 ...

  6. java数据结构 队列_Java数据结构之队列

    public class MyQueue { int[] elements; public MyQueue() { elements = new int[0]; } //入队 public void ...

  7. java数据结构系列——排列(2):有序阵列

    package Array;/*** 对数组排序.当添加到阵列保持有序数组元素:* @author wl**/ public class MyOrderArray {private long arra ...

  8. Silverlight 打印

    摘自:http://www.cnblogs.com/jiajiayuan/archive/2012/04/13/2444246.html Silverlight中的打印只有一个类,那就是PrintDo ...

  9. Lucene6.5.0 下中文分词IKAnalyzer编译和使用

    前言 lucene本省对中文分词有支持,不过支持的不好,其分词方式是机械的将中文词一个分成一个进行存储,例如:成都信息工程大学,最终分成为::成|都|信|息|工|程|大|学,显然这种分词方式是低效且浪 ...

最新文章

  1. 计算机基础学习必看书籍汇总
  2. JWT 应该保存在哪里?
  3. Jackson 框架使用说明,轻易转换JSON【转】
  4. 机器学习数据挖掘笔记_14(GMM-HMM语音识别简单理解)
  5. 推荐搜索系统论文干货集锦(持续更新)
  6. linux 启动流详解
  7. hashcode java_java 的Object类的hashcode()方法具体是怎么实现的?
  8. Zookeeper日志文件事务日志数据快照
  9. andorid actionBar
  10. Linux设备驱动简析—PC重启源码分析
  11. loadrunner录制时web时,安全证书问题
  12. Nginx源码分析 - 主流程篇 - 平滑重启和信号控制(10)
  13. 谁说不能用 Python开发企业应用?
  14. Java学习——HashMap
  15. JDK8的shenandoah GC/zgc啥时能转正?
  16. python可以下载百度文库_不用下载券也能下载百度文库资料,Python帮你轻松搞定...
  17. springboot对接支付宝支付接口(详细开发步骤总结)
  18. 数字乡村建设浅谈(一):可行性、难点、思考
  19. Unity - RenderDoc 抓帧导出 FBX(带UV)
  20. 非飞行模式下,笔记本电脑不显示附近WiFi,并提示“适配器遇到与驱动程序或硬件相关的问题”——解决办法

热门文章

  1. [FAQ21007] 电信VoLTE开关默认值设置
  2. 开发用于互操作性的应用程序_云标准:确保云应用互操作性的工具
  3. 常用的9种数据分析方法
  4. 前端之扇形图实现案例
  5. “强者恒强”,零食江湖来到新赛点
  6. 血战力扣 332.零钱兑换
  7. initpki.dll加载失败 找不到指定的模块的解决办法
  8. ASO优化|标题、描述、关键词的最优策略
  9. [IDA Plugin] IDA插件收集
  10. android键盘广告,android键盘钢琴Lite郑永修改版+去广告