Problem 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
 
解题思路:
  不难理解,求 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了好久好久..     
 #include <cstdio>
#include <cstring>
using namespace std;
int c[],n,t,len,a;
int find(int l,int r,int num){
while(l<=r){ int mid=(l+r)>>; if(c[mid]<=num) l=mid+; else r=mid-; }
return l;
}
int main(){
scanf("%d",&t);
for(int k=;k<=t;k++){
printf("Case #%d:\n",k);
scanf("%d",&n);
len=; memset(c,,sizeof(c));
for(int i=;i<=n;i++){
scanf("%d",&a);
if(i==){ c[len]=a-i; continue; }
int pos=find(,len,a-i);
c[pos]=a-i;
if(len<pos) len=pos;
} printf("%d\n",n-len);
} return ;
}
 #include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define N 1000000+5
int c[N],a[N],b[N],n,t,nmax;
void modify(int x,int num){while(x<=nmax)c[x]=max(c[x],num),x+=x&-x;}
int query(int x){int s=;while(x>)s=max(c[x],s),x-=x&-x;return s;}
int main(){
scanf("%d",&t);
for(int k=;k<=t;k++){
printf("Case #%d:\n",k);
scanf("%d",&n);
memset(c,,sizeof(c)); nmax=;
for(int i=;i<n;i++){
scanf("%d",&a[i]);
a[i]-=i; b[i]=a[i];
}
sort(b,b+n);
int size=unique(b,b+n)-b;//离散化
for(int i=;i<n;i++){
a[i]=lower_bound(b,b+size,a[i])-b+;
nmax=max(a[i],nmax);//离散化以后再去标记最大值
}
for(int i=;i<n;i++)modify(a[i],query(a[i])+);//前缀最大值+1
printf("%d\n",n-query(nmax));
} return ;
}

HDU 5256 - 序列变换 ,树状数组+离散化 ,二分法的更多相关文章

  1. HDU 4325 Flowers(树状数组+离散化)

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 题意:给出n个区间和m个询问,每个询问为一个x,问有多少个区间包含了x. 思路: 因为数据量比较多,所以需 ...

  2. HDU 6348 序列计数 (树状数组 + DP)

    序列计数 Time Limit: 4500/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  3. BZOJ_5055_膜法师_树状数组+离散化

    BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...

  4. POJ 2299 【树状数组 离散化】

    题目链接:POJ 2299 Ultra-QuickSort Description In this problem, you have to analyze a particular sorting ...

  5. hdu4605 树状数组+离散化+dfs

    Magic Ball Game Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  6. Apple Tree POJ - 3321 dfs序列构造树状数组(好题)

    There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. ...

  7. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

  8. HDU 1394 树状数组+离散化求逆序数

    对于求逆序数问题,学会去利用树状数组进行转换求解方式,是很必要的. 一般来说我们求解逆序数,是在给定一串序列里,用循环的方式找到每一个数之前有多少个比它大的数,算法的时间复杂度为o(n2). 那么我们 ...

  9. HDU 4325 Flowers 树状数组+离散化

    Flowers Problem Description As is known to all, the blooming time and duration varies between differ ...

随机推荐

  1. 常用SQL Server分页方式

    假设有表ARTICLE,字段ID.YEAR...(其他省略),数据53210条(客户真实数据,量不大),分页查询每页30条,查询第1500页(即第45001-45030条数据),字段ID聚集索引,YE ...

  2. nth-child和nth-of-type的区别

    以前一般都用:nth-child,后来知道了:nth-of-type,然后就一般用nth-of-type 它们两有什么区别呢? 首先来看个现象: 假如有这样一个HTML结构 <div class ...

  3. C# 单例模式(转)

    C#设计模式学习笔记-单例模式 最近在学设计模式,学到创建型模式的时候,碰到单例模式(或叫单件模式),现在整理一下笔记. 在<Design Patterns:Elements of Resuab ...

  4. 表空间使用情况统计[z]

    SELECT UPPER(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小(M)", D.TOT_GROOT ...

  5. 基于vue2.0的一个分页组件

    分页组件在项目中经常要用到之前一直都是在网上找些jq的控件来用(逃..),最近几个项目用上vue了项目又刚好需要一个分页的功能.于是百度发现几篇文章介绍的实在方式有点复杂, 没耐心看自己动手造轮子写了 ...

  6. 如何在Eclipse中查看Android API源码以及support包源码

    http://my.eoe.cn/futurexiong/archive/181.html 开发第三方Android应用的,大多数人应该还是Eclipse结合ADT来开发.那么大多数时候我们可能希望点 ...

  7. C# 当前程序所有线程

    using System.Linq; var threads = System.Diagnostics.Process.GetCurrentProcess().Threads;var count = ...

  8. bzoj 1912 : [Apio2010]patrol 巡逻 树的直径

    题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #includ ...

  9. java学习:AWT组件和事件处理的笔记(1)--Frame

    1.java的抽象窗口工具包(AWT)中包含了许多类来支持GUI设计2.AWT由java的java.awt包提供3.再进行GUI编程时,要理解:容器类(Container),组件(component) ...

  10. QString转LPCWSTR

    QFileInfo info("./records.db"); std::string str = info.absoluteFilePath().toStdString(); / ...