HDU 5773 The All-purpose Zero(LIS特殊處理)

Problem Description
?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] <= 1000000).?? has a magic so that he can change 0 to any interger(He does not need to change all 0 to the same interger).?? wants you to help him to find out the length of the longest increasing (strictly) subsequence he can get.

Input
The first line contains an interger T,denoting the number of the test cases.(T <= 10)
For each case,the first line contains an interger n,which is the length of the array s.
The next line contains n intergers separated by a single space, denote each number in S.

Output
For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the length of the longest increasing subsequence he can get.

Sample Input
2
7
2 0 2 1 2 0 5
6
1 2 3 3 0 0

Sample Output
Case #1: 5
Case #2: 5

Hint
In the first case,you can change the second 0 to 3.So the longest increasing subsequence is 0 1 2 3 5.

比賽時沒想到怎麼弄。。貼一個官方題解。。還是不難理解的:

0可以轉化成任意整數,包括負數,顯然求LIS時儘量把0都放進去必定是正確的。因此我們可以把0拿出來,對剩下的做O(nlogn)的LIS,統計結果的時候再算上0的數量。爲了保證嚴格遞增,我們可以將每個權值S[i]減去i前面0的個數,再做LIS,就能保證結果是嚴格遞增的。

ac代碼:

#include <bits/stdc++.h>

using namespace std;

#define rep(i,a,n) for(int i = (a); i < (n); i++)
#define per(i,a,n) for(int i = (n)-1; i >= a; i--)
#define clr(arr,val) memset(arr,val,sizeof(arr))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pi acos(-1)
typedef long long LL;
typedef pair<int, int> pii;
const double eps = 1e-8;

int a[100005],ans[100005];
int main(int argc, char const *argv[]) {
    int t, n;
    scanf("%d", &t);
    int cas = 1;
    while(t--){
        scanf("%d", &n);
        clr(a, 0);
        clr(ans, 0);
        int len = 1;
        int cnt0 = 0;
        int tmp, tmpn = 1;
        rep(i, 1, n+1){
            scanf("%d",&tmp);
            if(tmp == 0) cnt0++;
            else a[tmpn++] = tmp - cnt0;
        }
        if(cnt0 == n) len = 0;
        else {
            ans[1] = a[1];
            rep(i, 2, tmpn){
                if(a[i] > ans[len]) ans[++len] = a[i];
                else {
                    int pos = lower_bound(ans+1, ans+len, a[i])-ans;
                    ans[pos] = a[i];
                }
            }
        }
        printf("Case #%d: %d\n", cas++, len + cnt0);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章