【百度之星初赛2】序列变换(最长上升子序列)

我们有一个数列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

http://acm.hdu.edu.cn/showproblem.php?pid=5256

另外一道 最少删去多少值使序列递增 也是一样的做法。

#include<iostream>  
#include<algorithm>  
#include<string>  
#include<map>  
#include<vector>  
#include<cmath>  
#include<queue>  
#include<string.h>  
#include<stdlib.h>  
#include<cstdio>  
#define ll long long  
using namespace std; 
const int maxn = 1e5+10;
int a[maxn];
int b[maxn];
int dp[maxn];
int main()
{
    int n,t,cas=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        int num=0,ans=0,tot=0;
        for(int i=0;i<n;i++){
            scanf("%d",&a[i]);
            a[i]-=i;  //这一步不可少(原来是往后+1,现在使所有数字平等)
          //if(a[i]<1){  
          //    ans++;    //如果题目要求是正整数的话要这样写
          //}  
          //else{  
          //    b[tot++]=a[i];  
          //}  
            b[tot++]=a[i];
        }
        int dnum=0;
        for(int i=0;i<tot;i++){
            int pos = upper_bound(dp,dp+dnum,b[i])-dp;
            if(pos==dnum) dp[dnum++]=b[i];   //当前长度的dp数组都小于b[i],<span style="font-family: Arial, Helvetica, sans-serif;">那么b[i]插入,长度+1</span>
            else dp[pos]=b[i];               //否则,将当前大于b[i]的这个值替换成b[i],使dp数组内的数字尽可能小(原来的dp[pos]已经变成无穷大)
        }
        ans=ans+tot-dnum;  //总数-dp数组长度
        printf("Case #%d:\n",cas++);
        printf("%d\n",ans);
    }
}


你可能感兴趣的:(【百度之星初赛2】序列变换(最长上升子序列))