hdu5256序列变换(非递减子序列)
生活随笔
收集整理的這篇文章主要介紹了
hdu5256序列变换(非递减子序列)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意(中文直接粘吧)
序列變換
Problem Description
? ? 我們有一個數列A1,A2...An,你現在要求修改數量最少的元素,使得這個數列嚴格遞增。其中無論是修改前還是修改后,每個元素都必須是整數。
請輸出最少需要修改多少個元素。
?
Input
第一行輸入一個T(1≤T≤10),表示有多少組數據
每一組數據:
第一行輸入一個N(1≤N≤105),表示數列的長度
第二行輸入N個數A1,A2,...,An。
每一個數列中的元素都是正整數而且不超過106。
Output
對于每組數據,先輸出一行
Case #i:
然后輸出最少需要修改多少個元素。
?
Sample Input
2
2
1 10
3
2 5 4
思路:
? ? ? 比較有意思的一個題,我的第一反應是n-上升子序列,這樣顯然不對,因為1 2 3 3 4 5這樣就是6-5=1,那個多出來的3怎么改都不行的,其實可以這樣轉化問題,我們把每個數字都對應減去他們的位置編號,比如
1 ? 2 ? 4 ?6 ? 9 ? 8
-1 -2 ?-3 -4 ?-5 ?-6
這樣得到
0 0 1 2 5 2
序列變換
Problem Description
? ? 我們有一個數列A1,A2...An,你現在要求修改數量最少的元素,使得這個數列嚴格遞增。其中無論是修改前還是修改后,每個元素都必須是整數。
請輸出最少需要修改多少個元素。
?
Input
第一行輸入一個T(1≤T≤10),表示有多少組數據
每一組數據:
第一行輸入一個N(1≤N≤105),表示數列的長度
第二行輸入N個數A1,A2,...,An。
每一個數列中的元素都是正整數而且不超過106。
Output
對于每組數據,先輸出一行
Case #i:
然后輸出最少需要修改多少個元素。
?
Sample Input
2
2
1 10
3
2 5 4
思路:
? ? ? 比較有意思的一個題,我的第一反應是n-上升子序列,這樣顯然不對,因為1 2 3 3 4 5這樣就是6-5=1,那個多出來的3怎么改都不行的,其實可以這樣轉化問題,我們把每個數字都對應減去他們的位置編號,比如
1 ? 2 ? 4 ?6 ? 9 ? 8
-1 -2 ?-3 -4 ?-5 ?-6
這樣得到
0 0 1 2 5 2
這樣做到底為了什么呢?就是為了排除相等的情況,第i個位置最少要比i+1個位置少1,而i最少要比i+2的位置少2,這樣的話,我們只要全部減去自己位置的編號就相當于直接處理好了所有的位置關系,處理好之后我們就直接n-最大非遞減子序列就行了,非遞減子序列可以按找遞增子序列的那個方法弄,簡單改下就行,還有注意可以用二分貪心的那個方法,普通暴力的方法會超時吧N*N的。總體的時間復雜度是O(n*log(n))的沒啥壓力。
#include<stdio.h> #include<string.h>#define N 100000 + 100int num[N] ,now[N];int main () {int t ,cas = 1 ,i ,n;int low ,up ,mid ,len;scanf("%d" ,&t);while(t--){scanf("%d" ,&n);for(i = 1 ;i <= n ;i ++){scanf("%d" ,&num[i]);num[i] -= i;}len = 1;now[1] = num[1];for(i = 2 ;i <= n ;i ++){low = 1 ,up = len;while(low <= up){mid = (low + up) >> 1;if(now[mid] <= num[i])low = mid + 1;else up = mid - 1;}now[low] = num[i];if(low > len) len ++;}printf("Case #%d:\n" ,cas ++);printf("%d\n" ,n - len);}return 0; }
總結
以上是生活随笔為你收集整理的hdu5256序列变换(非递减子序列)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu5253最小生成树
- 下一篇: POJ2155二维线段树