zoukankan      html  css  js  c++  java
  • 2015 百度之星 1005 序列变换 动态规划

    序列变换

    Time Limit: 20 Sec  Memory Limit: 256 MB

    题目连接

    http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=601&pid=1003

    Description

    我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。 请输出最少需要修改多少个元素。

    Input

    第一行输入一个T(1≤T≤10),表示有多少组数据

    每一组数据:

    第一行输入一个N(1≤N≤105),表示数列的长度

    第二行输入N个数A1,A2,...,An。

    每一个数列中的元素都是正整数而且不超过106。

    Output

    对于每组数据,先输出一行

    Case #i:

    然后输出最少需要修改多少个元素。

    Sample Input

    2
    2
    1 10
    3
    2 5 4

    Sample Output

    Case #1:
    0
    Case #2:
    1

    HINT

    题意

    题解:

    先减去下标,然后求最长上升子序列,这是道原题,见到很多次了= =

    答案就是n-最长上升子序列长度

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    using namespace std;
    
    const int MAXN=100010;
    int a[MAXN],b[MAXN];
    
    //用二分查找的方法找到一个位置,使得num>b[i-1] 并且num<b[i],并用num代替b[i]
    int Search(int num,int low,int high)
    {
        int mid;
        while(low<=high)
        {
            mid=(low+high)/2;
            if(num>=b[mid])  low=mid+1;
            else   high=mid-1;
        }
        return low;
    }
    int DP(int n)
    {
        int i,len,pos;
        b[1]=a[1];
        len=1;
        for(i=2;i<=n;i++)
        {
            if(a[i]>=b[len])//如果a[i]比b[]数组中最大还大直接插入到后面即可
            {
                len=len+1;
                b[len]=a[i];
            }
            else//用二分的方法在b[]数组中找出第一个比a[i]大的位置并且让a[i]替代这个位置
            {
                pos=Search(a[i],1,len);
                b[pos]=a[i];
            }
        }
        return len;
    }
    
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        int T    ;
        int iCase = 0;
        scanf("%d",&T);
        while(T--){
            iCase++;
            int n;
            scanf("%d",&n);
            for(int i = 1;i <= n;i++){
                scanf("%d",&a[i]);
                a[i] -= i;
            }
            printf("Case #%d:
    ",iCase);
            printf("%d
    ",n - DP(n));
        }
        return 0;
    }
  • 相关阅读:
    线程概念简介 什么是线程 多线程上篇(七)
    进程通信概念简介 多线程上篇(六)
    进程同步经典示例 多线程上篇(五)
    进程同步概念简介 多线程上篇(四)
    进程控制概念简介 多线程上篇(三)
    进行概念详解 多线程上篇(二)
    操作系统与程序运行以及进程简介 多线程上篇(一)
    Mybatis动态SQL简单了解 Mybatis简介(四)
    Mybatis sql映射文件浅析 Mybatis简介(三)
    Mybatis配置信息浅析 MyBatis简介(二)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4542608.html
Copyright © 2011-2022 走看看