P1108 低價購買

2022-05-05 20:03:07 字數 1502 閱讀 7566

題目描述

「低價購買」這條建議是在奶**票市場取得成功的一半規則。要想被認為是偉大的投資者,你必須遵循以下的問題建議:「低價購買;再低價購買」。每次你購買一支**,你必須用低於你上次購買它的**購買它。買的次數越多越好!你的目標是在遵循以上建議的前提下,求你最多能購買**的次數。你將被給出一段時間內一支**每天的**價,你可以選擇在哪些天購買這支**。每次購買都必須遵循「低價購買;再低價購買」的原則。寫乙個程式計算最大購買次數。

這裡是某支**的**清單:

日期 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8, 9 ,10 ,11, 12

** 68 ,69 ,54, 64,68 ,64 ,70 ,67 ,78 ,62, 98, 87

最優秀的投資者可以購買最多 44 次**,可行方案中的一種是:

日期 2 , 5 , 6 ,10

** 69, 68 ,64 ,62

輸入輸出格式

輸入格式:

第1行: n(1≤n≤5000) ,**發行天數

第2行: n 個數,是每天的****。

輸出格式:

兩個數:

最大購買次數和擁有最大購買次數的方案數, 當二種方案「看起來一樣」時(就是說它們構成的**佇列一樣的時候),這 2 種方案被認為是相同的。

資料範圍支援 \(o(n^)\) 第一問是經典的線性dp, 最長下降子串行求解即可

解決了第一問, 我們得到了乙個陣列 \(f[i]\) 表示以 \(i\) 結尾的最長下降子串行的長度。 第二問同樣採用 \(dp\) ,以 \(dp[i]\) 代表以 \(i\) 結尾的最長的情況下的方案數, 那麼和第一問類似, 我們判斷一下是不是最長, 在進行轉移, 有$$if(f[i] == f[j] + 1 \ and\ a[i] < a[j])dp[i] += dp[j];$$。 首先考慮邊界, 若是排除重複的情況, 當乙個數為開頭, 即 \(f[i] == 1\) 時其方案數為 \(1\) 。狀態轉移方程已經給出。 在考慮重複的情況。 依據題意, 兩個子串行重複當且僅當其完全相同,所以對於同樣高度的結尾, 當其最長序列長度相同時, 我們只保留乙個, 清零乙個即可。

#include#include#include#include#includeusing namespace std;

int rd()

while(c >= '0' && c <= '9')

return flag * out;

}const int maxn = 5019;

int num, a[maxn];

int f[maxn], dp[maxn];

int main()

} printf("%d ", ans);

for(int i = 1;i <= num;i++)

} int tim = 0;

for(int i = 1;i <= num;i++)

printf("%d\n", tim);

return 0;

}

P1108 低價購買

原題鏈結 d i 是以 i 這個位置結束的最長下降子串行的長度 第一問就是求個最長下降子串行 第二問 記錄以 i 這個位置結束 長度為d i 的下降子串行的方案總數 d i d j 1 1 j i 的 j 的方案數相加 但是當兩個不同的位置上存的數相同且均滿足上式時 就會產生重複 因為位置靠後的數肯...

P1108 低價購買

對於第一問很容易看出是求最長下降子串行,n2 的暴力就可解決。而第二問是求最優方案數 且不重複 需要判重。可以在求解最長下降子串行的基礎上增開乙個陣列 g g i 表示以 i 結尾,不同的最優方案數。include include include include include include in...

P1108 低價購買 DP

給定乙個序列,求最長下降子串行,及不重複的方案數。洛谷鏈結 最長下降子串行可以用 o n 2 的簡單dp來求。不難發現 在乙個元素互不相同的序列中,不會出現重複方案,因此可以通過dp累計答案 詳見 然後考慮去重,發現以x結尾的最長序列,位置靠後的x的方案會包括位置靠前的x的方案。因此可以刪除最後乙個...