怪盜基德是乙個充滿傳奇色彩的怪盜,專門以珠寶為目標的超級盜竊犯。而他最為突出的地方,就是他每次都能逃脫中村警部的重重圍堵,而這也很大程度上是多虧了他隨身攜帶的便於操作的滑翔翼。
有一天,怪盜基德像往常一樣偷走了一顆珍貴的鑽石,不料卻被柯南小朋友識破了偽裝,而他的滑翔翼的動力裝置也被柯南踢出的足球破壞了。不得已,怪盜基德只能操作受損的滑翔翼逃脫。
假設城市中一共有n幢建築排成一條線,每幢建築的高度各不相同。初始時,怪盜基德可以在任何一幢建築的頂端。他可以選擇乙個方向逃跑,但是不能中途改變方向(因為中森警部會在後面追擊)。因為滑翔翼動力裝置受損,他只能往下滑行(即:只能從較高的建築滑翔到較低的建築)。他希望盡可能多地經過不同建築的頂部,這樣可以減緩下降時的衝擊力,減少受傷的可能性。請問,他最多可以經過多少幢不同建築的頂部(包含初始時的建築)?
輸入資料第一行是乙個整數k,代表有k組測試資料。
每組測試資料報含兩行:第一行是乙個整數n,代表有n幢建築。第二行包含n個不同的整數,每乙個對應一幢建築的高度h,按照建築的排列順序給出。
對於每一組測試資料,輸出一行,包含乙個整數,代表怪盜基德最多可以經過的建築數量。
3
8300 207 155 299 298 170 158 65
865 158 170 298 299 155 207 300
102 1 3 4 5 6 7 8 9 10
6
69
n < 100;
0 < h < 10000;
k < 100.
這一題其實是最長上生序列與最長下降序列的結合,需要求出最長上公升序列的長度,與最小下降序列的長度,輸出較大的那乙個。
(我第一次做的時候,就只求了最長下降序列並輸出,不幸答案錯誤%>_
此為其一,其二,此題有多組測試資料,所以每一次使用陣列後,養成乙個好習慣,把陣列清零。
下面是清零函式及所需標頭檔案(一維,二維需要迴圈清零);
b[i](狀態)是表示從第i個開始最長的下降或上公升序列;
h[i]表示第i個的高度
memset(b,0,sizeof(b));//#include
memset(h,0,sizeof(h));
有了狀態,狀態轉移方程式就有了
b[i]=max(b[j]+1,b[i]);
於是 ·············································
就有了**的核心部分
1.求最長下降序列
for(int i=2;i
<=k;i++)
for(int j=1;j
if(h[j]>h[i])
b[i]=max(b[j]+1,b[i]);
2.最長上公升序列
for(int i=k-1;i>=1;i--)
for(int j=k;j>i;j--)
if(h[j]>h[i])
b[i]=max(b[j]+1,b[i]);
接下來,我們發現 (⊙o⊙)…
怎麼找到這個最長下降序列(上公升序列)呀?
其實,只需要乙個函式即可(或用迴圈列舉每乙個,找出最大的)
*max_element(b+1,b+k+1)+1;//b陣列第1個下標開始到第k個數中,從中選出最大的數。
有了這些,**也可以實現了!!!
#include
#include
#include
using
namespace
std;
int b[5005],h[5005];
int main()
return
0;}
怪盜基德的滑翔翼
描述 怪盜基德是乙個充滿傳奇色彩的怪盜,專門以珠寶為目標的超級盜竊犯。而他最為突出的地方,就是他每次都能逃脫中村警部的重重圍堵,而這也很大程度上是多虧了他隨身攜帶的便於操作的滑翔翼。有一天,怪盜基德像往常一樣偷走了一顆珍貴的鑽石,不料卻被柯南小朋友識破了偽裝,而他的滑翔翼的動力裝置也被柯南踢出的足球...
怪盜基德的滑翔翼
確定滑行方向後就轉化為了lis問題,原問題相當於正向和反向以h i h i h i 為結尾的最長上公升子串行長度,分別正向和反向各進行一次lis,取得最大值即可。如下圖所示,int ans 0 最多可以經過的建築數量 正向做一遍lis for int i 1 i n i dp i 1 for int...
openjudge 怪盜基德的滑翔翼
總時間限制 1000ms 記憶體限制 65536kb 描述 怪盜基德是乙個充滿傳奇色彩的怪盜,專門以珠寶為目標的超級盜竊犯。而他最為突出的地方,就是他每次都能逃脫中村警部的重重圍堵,而這也很大程度上是多虧了他隨身攜帶的便於操作的滑翔翼。有一天,怪盜基德像往常一樣偷走了一顆珍貴的鑽石,不料卻被柯南小朋...