hdu5256序列變換(非遞減子串行)

2021-07-03 02:37:01 字數 1279 閱讀 4101

題意(中文直接粘吧)

序列變換

problem description

我們有乙個數列a1,a2...an,你現在要求修改數量最少的元素,使得這個數列嚴格遞增。其中無論是修改前還是修改後,每個元素都必須是整數。

請輸出最少需要修改多少個元素。

input

第一行輸入乙個t(1≤t≤10),表示有多少組資料

每一組資料:

第一行輸入乙個n(1≤n≤105),表示數列的長度

第二行輸入n個數a1,a2,...,an。

每乙個數列中的元素都是正整數而且不超過106。

output

對於每組資料,先輸出一行

case #i:

然後輸出最少需要修改多少個元素。

sample input22

1 10

32 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#include#define n 100000 + 100

int num[n] ,now[n];

int main ()

len = 1;

now[1] = num[1];

for(i = 2 ;i <= n ;i ++)

now[low] = num[i];

if(low > len) len ++;

}printf("case #%d:\n" ,cas ++);

printf("%d\n" ,n - len);

}return 0;

}

HDU 5256 序列變換

題意 我們有乙個數列a1,a2.an,你現在要求修改數量最少的元素,使得這個數列嚴格遞增。其中無論是修改前還是修改後,每個元素都必須是整數。請輸出最少需要修改多少個元素。思想 第i個位置到第i k個位置可以使當中k 1個相等的數通過變換滿足題意,首先把i位置上的數減去i,消除位置的影響 1 2 4 ...

hdu5256 序列變換 dp LIS

點選開啟鏈結 思路 lis的變形,唯一不同的是條件a i i a j j 1,i j。因為要確保這兩個元素之間能插入i j 1個元素 每個數先減去它的下標,防止下面的情況發生 加入序列是1,2,2,2,3,這樣求上公升子串行是3,也就是要修改2個,但是中間的兩個2,變化範圍又不能超過 1,3 那麼這...

HDU 5256 序列變換 LIS變形

傳送們 5256 他讓求至少可以改變幾個數讓他們單調遞增 我們可以處理一下 讓每乙個數都減去i 這樣在後面求出的最長遞增子串行的每幾個數之間都有相應的空位使他變過來 然後求最長遞增子串行就可以啦 如 4 2 3 3 4 變為2 2 1 1 最長遞增子串行為2,2 或1 1 我們就可以變為2 3 4 ...