codevs 1576 最長嚴格上升子序列

題目鏈接:http://codevs.cn/problem/1576/
題目描述?Description

給一個數組a1, a2 ... an,找到最長的上升降子序列ab1<ab2< .. <abk,其中b1<b2<..bk。

輸出長度即可。

輸入描述?Input Description

第一行,一個整數N。

第二行 ,N個整數(N?<?=?5000)

輸出描述?Output Description

輸出K的極大值,即最長不下降子序列的長度

樣例輸入?Sample Input

5

9?3?6?2?7

樣例輸出?Sample Output

3

數據范圍及提示?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 { maxLen [i]: 1<=i < k 且 a[i ]< a[k]且 k≠1 } + 1
若找不到這樣的i,則maxLen[k] = 1

maxLen[k]的值,就是在a[k]左邊,“終點”數值小于a[k]?,且長度最大的那個上升子序列的長度再加1。因為a[k]左邊任何“終點”小于a[k]的子序列,加上a[k]后就能形成一個更長的上升子序列 。

 1 #include <stdio.h>
 2 #define maxN 5005
 3 int n,a[maxN],maxLen[maxN];//maxLen[k]表示以a[k]做為“終點”的最長上升子序列的長度
 4 int main(int argc, char *argv[])
 5 {
 6     int i,j;
 7     scanf("%d",&n);
 8     for(i=0;i<n;i++) {  scanf("%d",&a[i]); maxLen[i]=1;  }
 9     
10     for(i=1;i<n;i++)//枚舉所有子序列的終點 
11     {
12         for(j=0;j<i;j++)//枚舉以a[i]做終點的子序列中a[i]的前綴元素 
13         {
14             if(a[j]<a[i])//嘗試用a[j]做a[i]的直接前綴形成新的子序列 
15             {
16                 maxLen[i]=(maxLen[j]+1>maxLen[i]?maxLen[j]+1:maxLen[i]);
17             }
18         }
19     }
20     printf("%d\n",maxLen[n-1]);
21     return 0;
22 }

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

 1 #include <stdio.h>
 2 #define maxN 5005
 3 int main(int argc, char *argv[])
 4 {
 5     int i,j,t;
 6     int n,a[maxN],maxLen[maxN];//maxLen[k]表示以a[k]做為“終點”的最長上升子序列的長度
 7     int max;
 8     
 9     scanf("%d",&n);
10     for(i=0;i<n;i++) {  scanf("%d",&a[i]); maxLen[i]=1;  }
11     for(i=1;i<n;i++)//枚舉所有子序列的終點 
12     {
13         for(j=0;j<i;j++)//枚舉以a[i]做終點的子序列中a[i]的前綴元素 
14         {
15             if(a[j]<a[i])//嘗試用a[j]做a[i]的直接前綴形成新的子序列 
16             {
17                 maxLen[i]=(maxLen[j]+1>maxLen[i]?maxLen[j]+1:maxLen[i]);
18             }
19         }
20     }
21     max=maxLen[0];
22     for(i=1;i<n;i++)
23         if(maxLen[i]>max) max=maxLen[i];
24     printf("%d\n",max);
25     return 0;
26 }

?

思考題 : 如何改進程序,使之能夠輸出最長上升子序列 ?

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

參考代碼:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define maxN 5005
 4 int main(int argc, char *argv[])
 5 {
 6     int i,j,t;
 7     int n,a[maxN],maxLen[maxN];//maxLen[k]表示以a[k]做為“終點”的最長上升子序列的長度
 8     int max;
 9     int pre[maxN];
10     int c[maxN],maxIndex;
11     
12     memset(pre,-1,sizeof(pre));
13     
14     scanf("%d",&n);
15     for(i=0;i<n;i++) {  scanf("%d",&a[i]); maxLen[i]=1;  }
16     
17     for(i=1;i<n;i++)//枚舉所有子序列的終點 
18     {
19         for(j=0;j<i;j++)//枚舉以a[i]做終點的子序列中a[i]的前綴元素 
20         {
21             if(a[j]<a[i])//嘗試用a[j]做a[i]的直接前綴形成新的子序列 
22             {
23                 if(maxLen[j]+1>maxLen[i])
24                 {
25                     maxLen[i]=maxLen[j]+1;
26                     pre[i]=j;
27                 }
28             }
29         }
30     }
31     max=maxLen[0];
32     for(i=1;i<n;i++)
33         if(maxLen[i]>max) { max=maxLen[i]; maxIndex=i; }
34     printf("%d\n",max);
35     
36     j=0;
37     c[j++]=a[maxIndex];
38     while(pre[maxIndex]!=-1)
39     {
40         maxIndex=pre[maxIndex];
41         c[j++]=a[maxIndex];
42     }
43     for(i=j-1;i>=0;i--)
44     {
45         printf("%d ",c[i]);
46     }
47     printf("\n");
48     return 0;
49 }
View Code

?

?

輸出最長上升子序列的另一種思路:

 1 #include <stdio.h>
 2 int n,size,a[1005][5],s,ans,next;
 3 int main(int argc, char *argv[])
 4 {
 5     scanf("%d",&n);
 6     for(int i=0;i<n;i++)
 7     {
 8         int t;
 9         scanf("%d",&t);
10         a[i][0]=t;a[i][1]=1;a[i][2]=0;
11         //a[i][1]表示以a[i][0]開頭的最長上升子序列的長度。
12         //a[i][2]表示在以a[i][0]開頭的最長上升子序列中a[i][0]的下一個數在原序列中的下標。
13     }
14     
15     for(int i=n-2;i>=0;i--)
16     {
17         size=next=0;
18         for(int j=i+1;j<n;j++)
19             if(a[j][0]>a[i][0]&&a[j][1]>size) {size=a[j][1];next=j;}
20         if(size>0) {a[i][1]=size+1;a[i][2]=next;}
21     }
22     
23     ans=0;
24     for(int i=0;i<n;i++)
25         if(a[i][1]>a[ans][1]) ans=i;
26         
27     printf("%d\n",a[ans][1]);
28     
29     /*for(int i=0;i<n;i++)
30         printf("%d %d %d %d\n",a[i][0],a[i][1],a[i][2],i);*/
31     
32     int i=ans;
33     while(a[i][2]>0)
34     {
35         printf("%d ",a[i][0]);
36         i=a[i][2];
37     }
38     printf("%d\n",a[i][0]);
39     return 0;
40 }
View Code

?

測試OJ地址:

http://noi.openjudge.cn/ch0206/1759/

http://bailian.openjudge.cn/practice/2757/

?

轉載于:https://www.cnblogs.com/huashanqingzhu/p/7326739.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252142.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252142.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252142.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nginx服務器開啟緩存、反向代理

一、反向代理配置 1、反向代理服務器配置如下 反向代理就是需要這一行proxy_pass來完成。當我們要訪問后端web服務器的時候&#xff0c;我們只需要訪問代理服務器就可以了&#xff0c;此時代理服務器就充當后端web服務器的角色。proxy_pass依賴的模塊是&#xff1a; 至于后兩行…

Halcon:區域特征:select_shape(Regions : SelectedRegions : Features, Operation, Min, Max : )

Region特征一覽&#xff1a; 特征 英 譯 備注 area Area of the object 對象的面積 row Row index of the center 中心點的行坐標 column Column index of the center 中心點的列坐標 width Width of the region 區域的寬度 height Height of the…

Web應用主動偵測工具Skipfish

Web應用主動偵測工具SkipfishSkipfish是Kali Linux附帶的一個主動Web應用偵測工具。該工具會首先盡可能獲取所有網站路徑&#xff0c;進行訪問&#xff0c;然后根據返回的內容&#xff0c;檢測是否存在漏洞。該工具采用字典爆破和網頁爬行兩種方式獲取網站。一旦獲取網頁內容&a…

7步讓你get首個數據科學實習

由于數據科學的龐大和復雜&#xff0c;如果你沒有相關的實習經歷的話&#xff0c;成為數據科學家的道路將會更加艱巨和困難。即使是經驗豐富的人&#xff0c;實習也是轉型進入數據科學領域的一種有效方式。 那么&#xff0c;尋找數據科學實習有哪些技巧&#xff1f;本文總結了數…

Halcon:Image、region、xld常用的處理

一、讀取文件夾中的所有圖片 list_files (C:/Users/fuping.liu/Desktop/檳榔有無頭/有頭, [files,follow_links], ImageFiles) tuple_regexp_select (ImageFiles, [\(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$,ignore_case], ImageFiles)for Index :…

賽碼網算法: 上臺階 ( python3實現 、c實現)

上臺階 題目描述 有一樓梯共m級&#xff0c;剛開始時你在第一級&#xff0c;若每次只能跨上一級或二級&#xff0c;要走上第m級&#xff0c;共有多少走法&#xff1f;注&#xff1a;規定從一級到一級有0種走法。 輸入…

Halcon: 畸變矯正與標定(1)

1、 Halcon相機標定和圖像矯正 對于相機采集的圖片&#xff0c;會由于相機本身和透鏡的影響產生形變&#xff0c;通常需要對相機進行標定&#xff0c;獲取相機的內參或內外參&#xff0c;然后矯正其畸變。相機畸變主要分為徑向畸變和切向畸變&#xff0c;其中徑向畸變是由透…

conda install 出錯

在下載包時出現下面的錯誤&#xff1a; userdeMBP:pytorch user$ conda install -n deeplearning matplotlib Solving environment: failedCondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/main/osx-64/repodata.json.bz2> Elapsed…

算法入門經典 第三章

scanf 遇到tab或空格或換行符停下來1.例題2-1 7744問題 從數本身看 從個位數的數字看#include <iostream>#include<math.h>using namespace std; int main(){ for(int a1;a<9;a) { for(int b1;b<9;b) { int n1100*a11*b;//floor x 等于1的區間為[1,2),florr(…

Halcon :畸變矯正與標定(2)

相機標定1.相機標定是什么2.怎么使用halcon進行相機內外參標定&#xff1f; &#xff08;1&#xff09;搭建硬件1.**相機連好電腦&#xff0c;用相機廠家軟件打開相機&#xff0c;檢查一下相機是否正常。**2.**接下來使用halcon連接相機**&#xff08;2&#xff09;開始標定1.*…

jQuery2

一、層次選擇器 1、后代選擇器$("div p"):div中所有的p標簽元素 2、自帶選擇器$("div>p")&#xff1a;div中的子代是p的第一層元素 3、兄弟選擇器$("divp")和div是兄弟的p標簽 4、相鄰兄弟選擇器$("div~p")與div相鄰的p標簽 二、jQ…

HTTP協議詳解(轉載)

http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html 轉載于:https://www.cnblogs.com/youmei11/p/8608007.html

bzoj1016 [JSOI2008]最小生成樹計數

1016: [JSOI2008]最小生成樹計數 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6032 Solved: 2452[Submit][Status][Discuss]Description 現在給出了一個簡單無向加權圖。你不滿足于求出這個圖的最小生成樹&#xff0c;而希望知道這個圖中有多少個不同的最小生成樹。&…

http請求概述

當瀏覽器輸入網址后 瀏覽器首先向DNS域名解析服務器發送請求。DNS反解析&#xff1a;根據瀏覽器請求地址中的域名&#xff0c;到DNS服務器中找到對應的服務器外網IP地址通過找到外網IP&#xff0c;向對應的服務器發請求&#xff08;首先訪問服務器的WEB站點管理工具&#xff1a…

Halcon:二維仿射變換實例探究

二維仿射變換&#xff0c;顧名思義就是在二維平面內&#xff0c;對對象進行平移、旋轉、縮放等變換的行為&#xff08;當然還有其他的變換&#xff0c;這里僅論述這三種最常見的&#xff09;。 Halcon中進行仿射變換的常見步驟如下&#xff1a; ① 通過hom_mat2d_identity算子…

劍指Offer-數組中重復的數字

題目描述 在一個長度為n的數組里的所有數字都在0到n-1的范圍內。 數組中某些數字是重復的&#xff0c;但不知道有幾個數字是重復的。也不知道每個數字重復幾次。請找出數組中任意一個重復的數字。 例如&#xff0c;如果輸入長度為7的數組{2,3,1,0,2,5,3}&#xff0c;那么對應的…

CSS2--字體樣式

## CSS2 字體樣式 ##### font-family 字體族 - 規定元素的字體系列 - 把多個字體作為一個"回退"系統保存.保證瀏覽器的支持 - Microsoft YaHei, tahoma, arial, Hiragino Sans GB, sans-serif ##### font 字體類型 - 襯線字體(serif)&#xff1a;在字的筆劃開始及結束…

虛擬機中訪問連接在物理機上的攝像機(使用橋接)

最近在使用攝像機SDK做開發&#xff0c;開發好之后物理機上沒有環境&#xff0c;所以弄了個虛擬機進行測試&#xff0c;就如何在虛擬機中連接攝像機做下記錄。 步驟 &#xff11;.物理機上對虛擬機的適配器和攝像機的適配器設置為相同網段并進行橋接&#xff08;注意與攝像機網…

Halcon:手眼標定——眼在手外與眼在手上

為什么需要九點標定&#xff1f; 為了得到機械和相機的關系&#xff0c;就好比人的手和眼的關系。我們用手將一個物體放到空間的一個位置&#xff0c;用眼看到這個物體&#xff0c;這也存在兩個坐標系&#xff0c;一個是手所在的運動空間的坐標系&#xff0c;一個是視網膜上成像…

grep 正則匹配

\{0,n\}&#xff1a;至多n次 \{\ 匹配/etc/passwd文件中數字出現只是數字1次到3次 匹配/etc/grub2.cfg文件以一個空格開頭匹配一個字符的文件的所有行 顯示以LISTEN結尾的行 顯示匹配右邊以LISTEN結尾匹配一個或者多個空格的所有輸出 分組及引用&#xff1a;講一個或者多個字符…