`
qiemengdao
  • 浏览: 275863 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

从一列数中筛除尽可能少的数,使得从左往右看这些数是从小到大再从大到小

 
阅读更多

问题:从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。

解法:这是双端 LIS 问题,用 DP 的思想可解,目标规划函数 max{ b[i] + c[i] }, 其中 b[i] 为从左到右, 0 ~ i 个数之间满足递增的数字个数; c[i] 为从右到左, n-1 ~ i 个数之间满足递增的数字个数。最后结果为 n - max + 1。其中 DP 的时候,可以维护一个 inc[] 数组表示递增数字序列,inc[i] 为从小到大第 i 大的数字,然后在计算 b[i] c[i] 的时候使用二分查找在 inc[] 中找出区间 inc[0] ~ inc[i-1] 中小于 a[i] 的元素个数(low)。
源代码如下:

/** 
* The problem: 
* 从一列数中筛除尽可能少的数使得从左往右看,这些数是从小到大再从大到小的(网易)。 
* use binary search, perhaps you should compile it with -std=c99 
* fairywell 2011 
*/  
#include <stdio.h>  
  
#define MAX_NUM    (1U<<31)  
  
int  
main()  
{  
    int i, n, low, high, mid, max;  
      
    printf("Input how many numbers there are: ");  
    scanf("%d/n", &n);  
    /* a[] holds the numbers, b[i] holds the number of increasing numbers 
    * from a[0] to a[i], c[i] holds the number of increasing numbers 
    * from a[n-1] to a[i] 
    * inc[] holds the increasing numbers 
    * VLA needs c99 features, compile with -stc=c99 
    */  
    double a[n], b[n], c[n], inc[n];  
      
    printf("Please input the numbers:/n");  
    for (i = 0; i < n; ++i) scanf("%lf", &a[i]);  
      
    // update array b from left to right  
    for (i = 0; i < n; ++i) inc[i] = (unsigned) MAX_NUM;  
    //b[0] = 0;  
    for (i = 0; i < n; ++i) {  
        low = 0; high = i;  
        while (low < high) {  
            mid = low + (high-low)*0.5;  
            if (inc[mid] < a[i]) low = mid + 1;  
            else high = mid;  
        }  
        b[i] = low + 1;  
        inc[low] = a[i];  
    }  
      
    // update array c from right to left  
    for (i = 0; i < n; ++i) inc[i] = (unsigned) MAX_NUM;  
    //c[0] = 0;  
    for (i = n-1; i >= 0; --i) {  
        low = 0; high = i;  
        while (low < high) {  
            mid = low + (high-low)*0.5;  
            if (inc[mid] < a[i]) low = mid + 1;  
            else high = mid;  
        }  
        c[i] = low + 1;  
        inc[low] = a[i];  
    }  
      
    max = 0;  
    for (i = 0; i < n; ++i )  
        if (b[i]+c[i] > max) max = b[i] + c[i];  
        printf("%d number(s) should be erased at least./n", n+1-max);  
        return 0;  
}  



分享到:
评论

相关推荐

    论文研究-胶囊内窥镜冗余图像数据自动筛除方法.pdf

    针对胶囊内窥镜检查的海量图像数据, 提出基于归一化互信息量及归一化互相关系数的冗余图像数据筛除方法。将图像在HSV色彩空间量化聚类; 然后计算相邻图像的相似度系数, 最后根据相似筛除比例进行迭代筛除。针对49例...

    一种新型种子生产输送振动筛除杂装置的制作方法.docx

    一种新型种子生产输送振动筛除杂装置的制作方法旨在解决现有种子生产中振动筛除杂效率不高、灰尘处理不便的问题。这种装置集输送、筛选和除尘功能于一体,提高了种子生产的效率和清洁度。 该装置的核心组成部分包括...

    蓝桥杯历届试题 算法分析+递归算法、 动态规划+构图、 递归算法、 度的计算+最短路径、 深度优先遍历+构图, 最小生成树+筛除

    蓝桥杯历届试题 算法分析+递归算法、 动态规划+构图、 递归算法、 度的计算+最短路径、 深度优先遍历+构图, 最小生成树+筛除  格子刷油漆 ( 递归算法、 动态规划)  网络寻路 ( 构图、 递归算法、 度的计算)...

    线性筛法求素数的原理与实现

    prime中是所有的素数按从小到大排列 pnum表示素数的个数 */ void CreatePrime(){ pnum = 0; // 初始化没有素数 // 先将所有数看做素数,然后开始筛选 for(int i = 0; i ; i++){ flag[i] = 1; } // 遍历筛去...

    数字图书馆信息生态链的信息流转研究.docx

    2. **信息流转的双向性**:信息从上游到下游,再从下游返回上游,形成闭环。 3. **信息删减与信息增加的同时性**:信息流转过程中既会因去除冗余信息而减少,也会因为加工创造而增加。 #### 2. 数字图书馆信息生态...

    艾托色尼法验证素数

    3. 接下来,找到数组中下一个未被标记的数(也就是下一个素数),比如3,标记3的所有倍数为`false`。 4. 重复这个过程,直到遍历到数组的平方根。这是因为一个数的因数不会超过它的平方根,所以超过这个范围的倍数...

    算法 数据结构函数实现模板

    2. **遍历处理**:从2开始遍历到`MAX`,对于每个数`i`,如果它是素数(即`bp[i]`为`true`),则将其添加到素数数组`p`中,并更新`phi[i]`和`e[i]`的值。 3. **筛除非素数**:对于每个已知素数`p[j]`,计算`i*p[j]`...

    visual basic常用算法大全

    VB程序可以使用数组标记非素数,从2开始逐个筛除其倍数。 4. **求和**: - 数列求和,如等差数列、等比数列的求和,可以通过公式直接计算,或者在VB中用循环累加求和。 5. **其他常见算法**: - **查找算法**:...

    小鹏汽车2019春招车联网软件工程师笔试题-互联网中心.docx

    **题目描述**:10000个人按照编号顺序报数,每轮将编号为偶数的人筛除,直到最后只剩一个人。 **解答**:此题考查的是数学中的序列和逻辑思维能力。可以通过分析每次筛选后的编号规律得出最终答案。经过多轮筛选,...

    Sifting Function Partition by Intervals for the Goldbach Problem

    筛法是一种从自然数中筛选出素数的工具,最著名的有埃拉托斯特尼筛法,以及后来的塞尔伯格筛法等。筛法的核心思想是通过逐步排除非素数的数字,来集中研究素数的性质和分布。在解决金巴问题中,研究者们通常利用各种...

    Sifting Function Partition by Integer Sort for the Goldbach Problem

    从这篇论文的内容来看,作者宋富高在高斯巴猜想的研究领域提出了具有创新性的研究方法,这种方法通过减少需要筛选的合数数量,并利用代数与筛法理论的结合,显著降低了问题的难度,使得高斯巴猜想的证明成为可能。...

    Python开发基于边界跟踪算法的可逆水印可视化项目源码+项目说明+数据.zip

    其代表若干个已切分的块,以可嵌入信息从大到小排列(若相同则以边界最左一列的最上一点坐标作为特征,以其横坐标从大到小排序,若再相同则对比纵坐标)。排除内部点小于等于2的边界。 ### *关于如何判断内部点的...

    素数的模30标记与存储

    可以预先生成标记文件,需要判断一个数是否为素数时,直接查询标记文件,无需每次都进行素数筛选运算,尤其在需要大量素数的加密算法中,可以极大地提高效率,甚至可以将标记文件固化到硬件中,提升读取速度。...

    计算机程序设计基础——第四讲PPT课件.pptx

    首先,我们来看一个实例,该实例使用C语言编写,目的是找出10只羊中体重最重的一只。代码中定义了一个名为`sheep`的数组,用来存储10只羊的体重,每个元素都是浮点类型。数组`sheep`的定义方式是`float sheep[10];`...

    模30剩余类的素数分析

    接着,函数排除被P0中的素数整除的数,然后以更高效的方式筛除P类剩余数,这一步骤减少了大约四分之三的计算量。 此外,文章还对18亿范围内的P类剩余素数进行了统计分析。作者将k值分为6个等差区间,每个区间有10^7...

    不同存储方式上求素数的

    埃拉托斯特尼筛法是一种高效的求素数的方法,它利用布尔数组来标记哪些数是素数。 1. **步骤**: - 初始化布尔数组`prime[2...n]`,所有元素初始值为`true`。 - 遍历数组,对于每个标记为`true`的索引`i`,将`i`...

Global site tag (gtag.js) - Google Analytics