我们有一个数列A1,A2...An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。
请输出最少需要修改多少个元素。
请输出最少需要修改多少个元素。
Input
第一行输入一个
T(1≤T≤10)
,表示有多少组数据
每一组数据:
第一行输入一个 N(1≤N≤105) ,表示数列的长度
第二行输入N个数 A1,A2,...,An 。
每一个数列中的元素都是正整数而且不超过 106 。
每一组数据:
第一行输入一个 N(1≤N≤105) ,表示数列的长度
第二行输入N个数 A1,A2,...,An 。
每一个数列中的元素都是正整数而且不超过 106 。
Output
对于每组数据,先输出一行
Case #i:
然后输出最少需要修改多少个元素。
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);
}
}