题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5256
题目要求的目标状态是求得最小的调整数使得这个序列变成一个严格递增的序列。
仔细思考,如果是让我们求一个不严格的递增序列的话很简单,那就简单了很多,此时最小调整数就是:n-最长不严格递增序列的长度,这个问题很好想,所以如果我们能把这个这个问题转换成求最小的调整数使得这个序列变成一个不严格的递增序列的话,那么问题就会简单很多。
我们用到的方法就是把每一位a[i]都减去一个i,这样我们再求这个序列的最小的调整数使得这个序列变成一个不严格的递增序列的话,就相当于求解原序列最小的调整数使得这个序列变成一个严格递增的序列,大家可以仔细思考一下其中的原因,还是比较好理解。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int a[maxn],dp[maxn],n;
int get_len()
{
int len = 1,pos;
dp[1] = a[1];
for(int i=2; i<=n; i++)
if(a[i] >= dp[len])
dp[++len] = a[i];
else
{
pos = upper_bound(dp+1, dp+len+1, a[i])-dp;
dp[pos] = a[i];
}
return len;
}
int main()
{
int T,t=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
a[i] -= i;
}
printf("Case #%d:\n%d\n", t++, n-get_len());
}
}