分析:
一个数前面有多少个零,就用它来减去这些零数,这样做的目的是尽量多选0,但是压缩当前值.对于两个数,他们的差距减小了,它们之间的0的个数,这不影响先后的值.
去掉所有的零后,再对当前序列求LIS,最后再加上0的个数.
总得来说,这种策略让所有的0的被用到了.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define sa(x) scanf("%d", &(x))
#define pr(x) cout << #x << ": " << x
#define pl(x) cout << #x << ": " << x << endl
struct jibancanyang
{
int A[112345], n, dp[112345];
void fun() {
int T;
sa(T);
for (auto cas = 1; cas <= T; ++cas) {
sa(n);
int zero = 0;
for(int i = 0; i != n; ++i) {
sa(A[i]);
if (A[i] != 0) A[i] -= zero;
else ++zero, --i, --n;
}
fill(dp, dp + n, static_cast<int>(1e9));
for (int i = 0; i != n; ++i) {
*lower_bound(dp, dp + n, A[i]) = A[i];
}
printf("Case #%d: %d\n", cas, (lower_bound(dp, dp + n, int(1e9)) - dp
+ zero));
}
}
}ac;
int main()
{
#ifdef jibancanyangs
freopen("in.txt", "r", stdin);
#endif
ac.fun();
return 0;
}