題解 P1108 低價購買

2022-05-07 21:48:10 字數 1096 閱讀 9151

題目鏈結

題目大意:求乙個數列的最長下降子串行長度,以及長度最長的下降子串行的數量

動態規劃

題目分析:求最長下降子串行是常規操作了,可以直接用樸素\(o(n ^ 2)\)演算法,也可以用二分做到\(o(nlogn)\)複雜度,不過\(n \leq 5000\)樸素演算法隨便跑

那麼如何統計方案呢?

我們\(dp\)求最長下降子串行是設\(d(i)\)表示以\(i\)結尾的下降子串行的最長長度.同理,我們可以用\(f(i)\)表示以\(i\)結尾,長度為\(d(i)\)的下降子串行的個數

不難想到\(f(i) = \begin 1 \qquad d(i) == 1 \\ \sum_^\ \end\)

但是這麼做是有問題的,原因在於重複統計

假如有\(d(i) == d(j)\)並且\(a(i) == a(j)\),且滿足$i \(,有\)f(i) \leq f(j)$

道理很簡單,因為\(f(i)\)的所有方案都被\(f(j)\)所包括了,這時你需要將\(f(j)\)置為\(0\),不然\(f(j)\)的方案會被統計多次

**奉上,資料規模小就寫的\(o(n ^ 2)\)演算法

#include #include using namespace std;

const int maxn = 8192;

int val[maxn],g[maxn],d[maxn],f[maxn],n,ans;//val為原數列,d[i]表示以i結尾的最長下降子串行長度,f[i]表示以i結尾,長度為d[i]的下降子串行的數量

int main()

d[i] = k + 1;

g[k + 1] = val[i];

ans = max(ans,d[i]);

} cout << ans << " ";//求lis,沒啥好說的

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

int sum = 0;

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

cout << sum << '\n';

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 低價購買

題目描述 低價購買 這條建議是在奶 票市場取得成功的一半規則。要想被認為是偉大的投資者,你必須遵循以下的問題建議 低價購買 再低價購買 每次你購買一支 你必須用低於你上次購買它的 購買它。買的次數越多越好 你的目標是在遵循以上建議的前提下,求你最多能購買 的次數。你將被給出一段時間內一支 每天的 價...