算法提高 聰明的美食家
如果有人認爲吃東西只需要嘴巴,那就錯了。
都知道舌頭有這麼一個特性,“由簡入奢易,由奢如簡難”(據好事者考究,此規律也適合許多其他情況)。具體而言,如果是甜食,當你吃的食物不如前面剛吃過的東西甜,就很不爽了。
大寶是一個聰明的美食家,當然深諳此道。一次他來到某小吃一條街,準備從街的一頭吃到另一頭。爲了吃得爽,他大費周章,得到了各種食物的“美味度”。他拒絕不爽的經歷,不走回頭路而且還要爽歪歪(爽的次數儘量多)。
輸入格式:
兩行數據。
第一行爲一個整數n,表示小吃街上小吃的數量
第二行爲n個整數,分別表示n種食物的“美味度”
輸出格式:
一個整數,表示吃得爽的次數
輸入樣例:
在這裏給出一組輸入。例如:
10
3 18 7 14 10 12 23 41 16 24
輸出樣例:
在這裏給出相應的輸出。例如:
6
數據規模和約定
美味度爲0到100的整數
n<1000
思路:
這道題是求最長不降子序列,顧名思義:就是最長的、值不下降的、不一定連續的序列長度。首先我們建立一個長度爲x數組arr用於存題目給出的序列,再建立一個同樣長度的數組dp,初始值爲1,後做兩重循環,第一重i從0到x,第二重j從0到i,只要當目前下標j的值小於當前i的值,dp對應的值取當前dp[i]和dp[j]+1的較大值,即當前能構成的最長的序列。
狀態轉換公式:
初值 :dp[i]=1
dp[i]=max(dp[i],dp[j]+1) arr[i]>=arr[j], j<=i
其中dp[i]表示以字符arr[i]結尾的最長連續非遞減字串,即i之前的最長的不降的序列。最後取dp中的最大的值。
最長不降子序列的方法和思路就是這樣,但是最好自己動手演算一下,才能更清晰的理解這個算法。
代碼:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int x;
cin >> x;
vector<int>arr(x);//存題目給出序列
vector<int>dp(x, 1);//存i位置的能構成的最長不降序列
for (int i = 0; i < x; i++)
{
cin >> arr[i];
}
for (int i = 0; i < x; i++)
{
for (int j = 0; j < i; j++)
{
if (arr[j] <= arr[i])
dp[i] = max(dp[i], dp[j] + 1);
}
}
int m = dp[0];
for (int i = 0; i < x; i++)
{
m = max(m,dp[i]);
}
cout << m << endl;
return 0;
}