zoukankan      html  css  js  c++  java
  • HDU 5256

    Problem Description
    我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。
    请输出最少需要修改多少个元素。
     
    Input
    第一行输入一个T(1T10),表示有多少组数据

    每一组数据:

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

    第二行输入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
     
    解题思路:
      不难理解,求 a[i]-i 的最长非递减子序列长度 len ,然后 n-len 就是答案了;
      以下有两份代码;
      代码一:
        二分法,打模板即可;时间复杂度O(nlog(n))
      代码二:
        树状数组,前缀最大值的应用。 时间复杂度也是 O(nlog(n))
        回想求LIS的动态规划过程 dp[i]=max(dp[j]); (i>j&&h[j]<h[i])
        利用树状数组的性质: dp[i]=query(a[i]);
        但这道题上还有很多问题,比如负数的存在,应此需要离散化;
        应注意离散化后再去标记最大值,WA了好久好久..     
     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 int c[1000000],n,t,len,a;
     5 int find(int l,int r,int num){
     6     while(l<=r){ int mid=(l+r)>>1; if(c[mid]<=num) l=mid+1; else r=mid-1; }
     7     return l;
     8 }
     9 int main(){
    10     scanf("%d",&t);
    11     for(int k=1;k<=t;k++){
    12         printf("Case #%d:
    ",k);
    13         scanf("%d",&n);
    14         len=1; memset(c,0,sizeof(c));
    15         for(int i=1;i<=n;i++){
    16             scanf("%d",&a);
    17             if(i==1){ c[len]=a-i; continue;    }
    18             int pos=find(1,len,a-i);
    19             c[pos]=a-i;
    20             if(len<pos) len=pos;
    21         }    printf("%d
    ",n-len);
    22     } return 0;
    23 }
     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 using namespace std;
     5 #define N 1000000+5
     6 int c[N],a[N],b[N],n,t,nmax;
     7 void modify(int x,int num){while(x<=nmax)c[x]=max(c[x],num),x+=x&-x;}
     8 int query(int x){int s=0;while(x>0)s=max(c[x],s),x-=x&-x;return s;}
     9 int main(){
    10     scanf("%d",&t);
    11     for(int k=1;k<=t;k++){
    12         printf("Case #%d:
    ",k);
    13         scanf("%d",&n);
    14         memset(c,0,sizeof(c)); nmax=0;
    15         for(int i=0;i<n;i++){
    16             scanf("%d",&a[i]);
    17             a[i]-=i; b[i]=a[i]; 
    18         } 
    19         sort(b,b+n); 
    20         int size=unique(b,b+n)-b;//离散化 
    21         for(int i=0;i<n;i++){
    22             a[i]=lower_bound(b,b+size,a[i])-b+1;
    23             nmax=max(a[i],nmax);//离散化以后再去标记最大值 
    24         } 
    25         for(int i=0;i<n;i++)modify(a[i],query(a[i])+1);//前缀最大值+1 
    26         printf("%d
    ",n-query(nmax));
    27     } return 0;
    28 }
    我自倾杯,君且随意
  • 相关阅读:
    sqlplus中设定行大小、页大小、字符列格式、数字列格式、清屏
    位图索引
    B树索引
    Oracle列自增实现(3)-DEFAULT Values Using Sequences
    Oracle列自增实现(2)-Identity Columns in Oracle Database 12c Release 1 (12.1)
    oracle列自增实现(1)-Sequence+Trigger实现Oracle列自增
    ORA-01502: 索引或这类索引的分区处于不可用状态
    Oracle中的rowid
    Multitenant Architecture---PDB与CDB
    ODI Studio拓扑结构的创建与配置(Oracle)
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5167903.html
Copyright © 2011-2022 走看看