noip類比【noname】

來源:互聯網
上載者:User

標籤:tchar   lse   問題   個數   stdin   freopen   就是   簡單的   nlogn   

noname

【問題描述】

    給定一個長度為n的正整數序列,你的任務就是求出至少需要修改序列中的多少個數才能使得該數列成為一個嚴格(即不允許相等)單調遞增的正整數序列,對序列中的任意一個數,你都可以將其修改為任意的正整數。

      

【輸入格式】

每個測試點第一行為一個正整數T,表示該測試點內的資料群組數,你需要對該測試點內的T組資料都分別給出正確的答案才能獲得該測試點的分數。

    接下來T組資料,每組資料第一行一個正整數n,表示序列長度,接下來一行n個正整數描述這個序列。

 

【輸出格式】

對於每一組測試資料輸出一行一個非負整數表示答案。

【輸入輸出範例】

noname.in

noname.out

4

3

1 1 2

3

2 2 3

4

1 2 3 4

4

2 3 3 4

2

1

0

2

 

 

【範例解釋】

    第一組資料中,由於正整數的限制,只能修改序列中第2、3個數。

    第二組資料中,將第一個數修改為1即可。

    第三組資料已經符合條件,不需要修改。

    第四組資料中,由於正整數的限制,只修改一個數並不能完成任務,而需要同時修改前兩個數或者後兩個數。

 

【資料規模與約定】

      對於30%的資料,有1≤n≤10。

      對於80%的資料,有1≤n,T≤50,且輸入序列中每個數均不超過50。

      對於100%的資料,有1≤n≤50000,1≤T≤5000,輸入序列中每個數均為不超過1000000000(10^9)的正整數,且每個測試點中T組資料對應的n值總和不超過500000。

 

【題解思路】

這題看著怎麼這麼像LIS啊?(:霧

回顧一下dp入門題LIS ?

依稀記得這題是可以二分最佳化的吧:O(n^2) à O(nlogn)

 

我們思考類型題:

  1. 把一個序列改成非嚴格單調遞增的(單調不下降的),至少需要修改多少個數?

    A:用該序列總長度減去最長不下降子序列的長度。

    2.那麼把一個序列改成嚴格單增的呢?

    A:用該序列總長度減去最長上升子序列的長度?標準錯答案啊。

    正解是:構造序列B[i] = A[i] – i;答案即為序列總長度減去B的最長不下降子序列。

    Why???  因為要求嚴格單調遞增,所以前一項與後一項至少相差一,將這個必要的差值減去,就相當於求B改成非嚴格單增最少需修改的數,也就相當於第一個問題。

    3.(本題)在2的條件下把整數改成了正整數。題目意思就變成:求首項為非負整數的最長上升子序列。

 

那豈不是很簡單的一個dp ???當然還是需要二分最佳化的啦。

#include<bits/stdc++.h> using namespace std;const int maxx= 100001;int a[maxx],b[maxx],n,T,f[maxx],len;inline int read(){    int x=0,f=1; char ch=getchar();    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}    return x*f;}int find(int x){        int l = 1,r = len + 1;    if(x < f[1])return 0;    while(l+1 < r){            int m = l + r>>1;        if(f[m] <= x) l=m;        else r = m;    }        return l;}    void work(){        len = 0;    for(int i = 1;i <= n;i++){        if(b[i] < 0)continue;        int id = find(b[i]);        len = max(id + 1,len);        f[id+1] = min(f[id+1],b[i]);    }        printf("%d\n",n-len);}    int main(){    freopen("noname.in","r",stdin);    freopen("noname.out","w",stdout);    T = read();    while(T--){        n = read();        memset(f,0x3f,sizeof(f));        for(int i = 1;i <= n; ++i){            a[i] = read();            b[i] = a[i] - i;        }        work();        }    return 0;}

 

noip類比【noname】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.