DP入門之最長降序子列

2021-06-06 02:00:02 字數 1938 閱讀 5512

想看更多的解題報告:

攔截飛彈

某國為了防禦敵國的飛彈襲擊,開發出一種飛彈攔截系統。但是這種飛彈攔截系統有乙個缺陷:

雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於前一發的高度。

某天,雷達捕捉到敵國的飛彈來襲,並觀測到飛彈依次飛來的高度,請計算這套系統最多能攔截多少飛彈。

攔截來襲飛彈時,必須按來襲飛彈襲擊的時間順序,不允許先攔截後面的飛彈,再攔截前面的飛彈。

輸入有兩行,

第一行,輸入雷達捕捉到的敵國飛彈的數量k(k<=25),

第二行,輸入k個正整數,表示k枚飛彈的高度,按來襲飛彈的襲擊時間順序給出,以空格分隔。

輸出只有一行,包含乙個整數,表示最多能攔截多少枚飛彈。

我們拿300 207 155 300 299 170 158 65舉例

用a[1..i]表示第i個飛彈的高度,用f[1..i]表示第i個飛彈最多能打f[i]個飛彈,即第i個的最長降序子列。那麼我們從最後到第乙個開始分析,可以肯定的是,最後乙個的最長降序子列肯定是1,即自己本身,那麼第二個如果比第乙個高,那麼就是2,否則就是1.這個很容易理解,相對於第三個,如果比第乙個高,那麼是f[n-2] = f[n] + 1,如果比第二個高,那麼f[n-2] = f[n-1] +1,那麼值最大的就是f[n-2]的值,依據這樣我們可以得到乙個表示式,f[i]=

int ans;

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

if (f[i] > ans) ans= f[i];

cout<< ans<< endl;

}int main()

合唱隊隊形

題目描述:

n 位同學站成一排,**老師要請其中的(n‐k)位同學出列,使得剩下的k位同學不交換位置

就能排成合唱隊形。

合唱隊形是指這樣的一種隊形:設k位同學從左到右依次編號為1,2,…,k,他們的身高分別為t1,t2,…,tk,則他們的身高滿足t1ti+1>…>tk(1<=i<=k)。

你的任務是,已知所有n 位同學的身高,計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。

根據前面最長子序列,我的想法是,i從1到k遍歷,以i為中心,算出從1到i的最長上公升子串行a,i到k的最長下降子串行b,那麼a+b-1就是以i為中心的剩下的最多的人數,那麼從1到k選個最大的就可以了。

**如下:

#include using namespace std;

#define maxv 100

int n,a[maxv];

int maxshangsheng(int t)

return temp[t];

}int maxxiajiang(int t)

return temp[t];

}int main()

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

} return 0;

}

但是這樣的缺點是,每次都要運算一邊求最長的上公升與下降子串行,會重複計算,並且消耗一定的時間,那麼我們可以只算一遍,就是將i從1到n開始,將i的最長上公升子串行儲存在a[i]中,同樣將i從n到1開始,將i的最長下降子串行儲存在b[i]中,那麼對於i的f[i],f[i]=a[i]+b[i]-1,這樣就可以節省很多時間,雖然多出了兩個陣列,這也是用空間換時間的乙個方法。

**如下:

#include using namespace std;

#define maxv 100

int n,a[maxv],l[maxv],r[maxv];

void init()

for(i=n;i>=1;i--)

}int main()

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

} return 0;

}

動態規劃之最長不降序子串行

用乙個陣列dp記錄以該元素開始的所對應最長不下降子串行的長度。初始化dp 經過迴圈執行後形成下表 程式如下 最長不下降子串行 include using namespace std int dp 105 int lis int a,int n else continue 防止倒數第二個元素dp自加1...

DP之最長上公升子串行

前言 我們先了解一下最長連續遞增子串行的求解!includeusing namespace std 求最長連續遞增序列 define maxn 100000 int n,a maxn dp maxn dp i 即前i個元素的上公升子串行的長度 int main int ans 0 for int i...

DP之最長上公升子串行

def lengthoflis self,nums 處理特殊情況 iflen nums 1 return len nums 儲存 該元素之前 的 最大上公升子串行的長度 mem 1 for in range len nums for j in range 1 len nums 前面的元素都要遍歷一遍...