AtCoder Beginner Contest 250 G,H
阿新 • • 發佈:2022-05-09
G
法1:
我們有一種顯然的貪心思路——對於一個\(i\),嘗試找到後面一個\(j\),滿足\(P_{j}>P_{i}\),在\(i\)時刻買入,在\(j\)時刻賣出。
這樣的做法顯然不對。
假設我們是在\(i\)時買入一個stonk,在\(j\)時賣出,而在\(k\)時賣出是最優解。那麼我們可以假設在\(j\)時刻賣出後,我們立刻以\(j\)的價格“嘗試”買入,然後在\(k\)時刻,發現前面有\(j\)時刻的stonk,則總價值為\(p_{j}-p_{i}+p_{k}-p_{j}\),那麼和\(i\)時買入\(k\)時賣出是沒有差異的。
我們使用堆去維護,對於\(i\)從\(1\)到\(n\)
法2:
假設\(a_{i}=1\)表示我們在\(i\)時刻買入stonk,\(a_{i}=-1\)表示我們在\(i\)時刻賣出stonk,\(a_{i}=0\)表示我們什麼都不做。
那麼我們的字首和\(sum_{i}=\sum_{j=0}^{i} a_{j}\)必須要滿足\(sum_{i}>0\)。
開始我們假設所有點都是\(a_{i}=1\)。
從大往小考慮\(p_{i}\):若我們選擇在\(i\)時刻賣出,那麼\(sum_{i},sum_{i+1},...\)
我們肯定儘可能將更多的點改為\(-1\),其次是\(0\)。所以對於\(\min_{j=i}^{n} sum_{j}\geq 2\)時,我們肯定選擇在\(i\)時刻賣出;對於\(\min_{j=i}^{n} sum_{j}=1\)時,我們選擇什麼都不做;否則我們選擇維持原樣。
這可以使用線段樹實現。