codevs 1576 最長嚴格上公升子串行

2021-09-21 16:20:19 字數 2444 閱讀 3372

題目描述 description

給乙個陣列a1, a2 ... an,找到最長的上公升降子串行ab1輸出長度即可。

輸入描述 input description

第一行,乙個整數n。

第二行 ,n個整數(n 

輸出描述 output description

輸出k的極大值,即最長不下降子串行的長度

樣例輸入 sample input

9 3 6 2 7

樣例輸出 sample output

資料範圍及提示 data size & hint

【樣例解釋】

最長不下降子串行為3,6,7

解題思路

參考:北大郭煒老師

1.找子問題:「求以ak( k=1, 2, 3…n)為終點的最長上公升子串行的長度」

乙個上公升子串行中最右邊的那個數,稱為該子串行的「終點」。

雖然這個子問題和原問題形式上並不完全一樣,但是只要這n個子問題都解決了,那麼這n個子問題的解中,最大的那個就是整個問題的解。

2. 確定狀態

子問題只和乙個變數-- 數字的位置相關。因此序列中數的位置k 就是「狀態」,而狀態 k 對應的「值」,就是以a[k]做為「終點」的最長上公升子串行的長度。狀態一共有n個。

3. 找出狀態轉移方程

maxlen [k]表示以

a[k]

做為「終點」的最長上公升子串行的長度那麼:

初始狀態: maxlen [1] = 1

maxlen[k]= max + 1

若找不到這樣的i,則maxlen[k] = 1

maxlen[k]的值,就是在a[k]左邊,「終點」數值小於a[k] ,且長度最大的那個上公升子串行的長度再加1。因為a[k]左邊任何「終點」小於a[k]的子串行,加上a[k]後就能形成乙個更長的上公升子串行 。

1 #include 2

#define maxn 5005

3int n,a[maxn],maxlen[maxn];//

maxlen[k]表示以a[k]做為「終點」的最長上公升子串行的長度

4int main(int argc, char *ar**)59

10for(i=1;i//

列舉所有子串行的終點

1118}19

}20 printf("

%d\n

",maxlen[n-1

]);21

return0;

22 }

上面的**寫錯了,抱歉。更正如下:

1 #include 2

#define maxn 5005

3int main(int argc, char *ar**)411

for(i=1;i//

列舉所有子串行的終點

1219}20

}21 max=maxlen[0

];22

for(i=1;i)

23if(maxlen[i]>max) max=maxlen[i];

24 printf("

%d\n

",max);

25return0;

26 }

思考題 : 如何改進程式,使之能夠輸出最長上公升子串行 ?

思路:新增pre[ ],其中pre[k]=x表示在a[ ]序列構成的若干個上公升子串行中,a[k[的前驅是a[x]。一開始pre[ ]全部初始化為-1表示一開始所有元素的前驅都是自己本身。在迴圈求解maxlen[i]的同時,更新pre[i]。最後在掃瞄出maxlen[ ]最大值為maxlen[i]以後,從pre[i]往前推即可。假如要順序輸出該最長上公升子串行,可以把逆推pre[ ]的過程儲存再輸出。

1 #include2 #include

3#define maxn 5005

4int main(int argc, char *ar**)516

17for(i=1;i//

列舉所有子串行的終點

1828}29

}30}31 max=maxlen[0

];32

for(i=1;i)

33if(maxlen[i]>max)

34 printf("

%d\n

",max);

3536 j=0

;37 c[j++]=a[maxindex];

38while(pre[maxindex]!=-1)39

43for(i=j-1;i>=0;i--)

4447 printf("\n"

);48

return0;

49 }

view code

Codevs 1576 最長嚴格上公升子串行

題目描述 description 給乙個陣列a1,a2 an,找到最長的上公升子串行 輸出長度即可。輸入描述 input description 第一行,乙個整數n。第二行 n個整數 n 5000 輸出描述 output description 輸出k的極大值,即最長不下降子串行的長度 樣例輸入 s...

1576 最長嚴格上公升子串行

給乙個陣列a1,a2 an,找到最長的上公升降子串行ab1 第一行,乙個整數n。第二行 n個整數 n 5000 輸出k的極大值,即最長不下降子串行的長度 9 3 6 2 7 按自己的思路隨便寫了乙個 include using namespace std int main for int i 0 i...

1576 最長嚴格上公升子串行

時間限制 1 s 空間限制 256000 kb 題目等級 gold description 給乙個陣列a1,a2 an,找到最長的上公升降子串行ab1 b2 bk,其中b1輸出長度即可。輸入描述 input description 第一行,乙個整數n。第二行 n個整數 n 5000 輸出描述 out...