此題的弱化版
和這個思路很相似
#include
#define int long long
using
namespace std;
int n,x,ans;
priority_queue<
int>q;
/*題解們都說:考慮當前的數x和之前的最大數y(預設x=y已經滿足非降了)
為了讓它非降,我們要做區間[x,y]裡找到乙個數z,使得y減小到z,x增大到z。
那麼可以發現,無論z取什麼,代價都是y-x。
不難看出,y減小的越多,後面的序列越容易變成非降,那麼只要讓y減小到x就好了。
看到這裡,我一直有乙個疑問,如果令y減小到x之後,序列不滿足非降了怎麼辦?
仔細想了想,實際上應該是這樣的:
為了讓序列非降,y不能小於y之前的最大值。
而由於y是整個序列的最大值,如果它之前的最大值z小於等於x,那麼將y減小到x仍能保證序列是非降的。
否則的話,z大於x小於y,仍是在區間[x,y]內,那麼移動的代價是y-x,所以用於更新答案是沒有問題的
那麼這裡為什麼要讓yy減到最小呢?
這是因為x和y不論如何調整,他們的代價之和都已經不變了,但問題是他們目前選的最優方案並不是之後的最優。
為了滿足他們在之後最優,只有把y減小到x,才能保證之後更有可能非降。
概括一下,對於當前的數,無論最優解如何,對答案的貢獻是一定的。
而為了保證之後的解也最優,令y減小到x,可以保證之後的解最優,且不會影響當前的最優解
-----by 義烏中學 bzt
看了他的部落格後,我覺得他的這個疑問就是我的疑問:如果令y減小到x之後,序列不滿足非降了怎麼辦?
但是看了他的解釋後,我覺得還是沒有解釋到位。
我們假設,第乙個數是5,第二個數是7,第三個數是2
那麼這時候,可以發現:上文中的z就是5,y就是7,x就是2,按照題目意思,我們需要把y變成2,ans+=(7-2)
這時候發現 這個序列不是非降了
那麼怎麼辦呢?
1.如果此時序列已經結束了,那麼我們可以把z變為5,y變為5,x變為5,ans+=5,不需要按照題目要求變化
2.如果此時序列沒有結束,那麼讀入下乙個數d,比如下乙個數是d=3,
按照題目意思,我們需要把z變為3,ans+=(5-3),ans=7 然後堆中的元素為 3,2,2,3
那麼這時候,我們可以把資料變為: z=5-2=3 y=7-4=3 x=2+1=3 d=3 ans=7
雖然我完全沒有按照題意的要求構造數,但是ans還是最小,等於7
也就是可以這樣理解,已經讀入的數相當於成立了乙個強大的聯盟,只需要花費按照**中的代價
那麼無論後面出現哪個數,都可以通過花費**中公式計算出的代價構造出乙個 陣列
使得這個陣列是非降的 !!!
夠強大吧!!!
也就是說,當前堆中的這些size個元素,並不是真正的最後的序列的前面的size個元素 ,而是乙個虛擬的!!!
所以,根本不會出現這個疑問: 如果令y減小的x之後,序列不滿足非降了怎麼辦?
這個思想,和 o(nlogn) 的lis的 b陣列 很相似 !!!
*/signed
main()
}printf
("%lld\n"
,ans)
;return0;
}
洛谷 P1645 序列
炒雞明顯的貪心題,主要就想讓一段區間與另一段裡面重合的數越多越好。於是先按照區間右端排序,然後盡可能的把數都往右靠攏,最後與另一段區間的前面的重合。然後可以用個flag來記錄哪些數被選了什麼的。include includeusing namespace std const int maxn 100...
洛谷 P1631 序列合併
題目描述 有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個。輸入輸出格式 輸入格式 第一行乙個正整數n 第二行n個整數ai,滿足ai ai 1且ai 10 9 第三行n個整數bi,滿足bi bi 1且bi 10 9.資料規模 對於50 的資料中,滿...
洛谷 P1631 序列合併
有兩個長度都是n的序列a和b,在a和b中各取乙個數相加可以得到n 2個和,求這n 2個和中最小的n個。第一行乙個正整數n 第二行n個整數ai,滿足ai ai 1且ai 10 9 第三行n個整數bi,滿足bi bi 1且bi 10 9.輸出僅一行,包含n個整數,從小到大輸出這n個最小的和,相鄰數字之間...