靠着小明的朝五晚九地經營共享單車,魔王堡的總算熬過了這一個月。可是好景不長,共享單車市場競爭的太激烈,小明的公司已經開始虧損了,再這麼下去吃棗藥丸。ios
統計局的工資可能都不夠虧的。爲保住本身褲衩不被當掉,Home_W正苦苦思索着策略,這時網上忽然出現了阿里巴巴用區塊鏈養豬的新聞,Home_W看到如今農業這麼火,靈機一動,決定辭掉統計局的工做,回農村種地,用大數據分析和人工智能搞生態農業。區塊鏈
如今Home_W要下鄉種地n天,天天他均可以從地中收穫到a[i]的蔬菜。同時第i天蔬菜的價格爲b[i]。大數據
Home_W 有一個發大財的心,因此他可能不會當即賣掉剛收穫上來的蔬菜,而是會屯幾天的菜,等到價格高了再一次性清倉所有賣掉。人工智能
可是每單位蔬菜每屯一天要花費1的電費用於製冷,好比,若單位電費爲1,第一、二、3天獲得蔬菜分別是3,2,1 那麼把這些蔬菜屯到第4天再賣,要花費3*3+2*2+1*1=14電費。咱們偉大Home_W 大魔王用大數據技術和魔力的組合完美預測出了這n天中,天天他能收穫的蔬菜數量和蔬菜天天的價格。因而他採spa
取了最優策策略來賣菜,那麼n天結束後他最多能賺到多少錢?code
單組數據,第一行是一個整數n表明天數orm
接下來一行 有n個數字 a1,a2,a3……an 表明天天收穫上來的蔬菜的數量blog
再接下一行 有n個數 字 b1,b2,b3……bn 表明蔬菜天天的價格 ip
1<=n<=5*105數據分析
0<ai,bi<=105
輸出一個整數,表明若是採起最優策略來賣菜,那麼n天結束後Home_W最多能賺到錢的數量.
注意賣的時候必須賣光,不能留任何蔬菜
8 7 9 8 3 5 5 6 9 4 9 4 3 3 7 4 5
318
hint:分別在次日,第六天,第八天賣出全部的蔬菜
/**
思路:
由於最後一天確定是得賣出的,因此以最後一天爲
最後一個狀態,往前面推。假設最後一天的價值爲
cost【n-1】,那麼前一個狀態對應的價值就會有兩個
一個是cost【n-2】,一個是cost【n-1】-1;從兩個狀態
中咱們固然是要選擇大的那個。若是說cost【n-2】大於cost【n-1】-1;
那麼咱們確定得選擇在這一天賣出,不能存到cost【n-1】再賣出。
而後每次賣出就改變比較的值,往前面比較。你可能會問爲何要改變。
由於cost【n-2】的狀態確定大於cost【n-1】-1,那麼再往前推一步,
cost【n-2】-1確定大於cost【n-1】-2;因此保留cost【n-2】去與
cost【n-3】進行比較就能夠了。
咱們能夠先標記在哪一天賣出,最後進行一次O(n)的計算就能夠得出答案了。
**/
附上代碼:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; const int MAXN = 5*1e5+5; ll gas[MAXN]; ll cost[MAXN]; int flag[MAXN]; /** 思路: 由於最後一天確定是得賣出的,因此以最後一天爲 最後一個狀態,往前面推。假設最後一天的價值爲 cost【n-1】,那麼前一個狀態對應的價值就會有兩個 一個是cost【n-2】,一個是cost【n-1】-1;從兩個狀態 中咱們固然是要選擇大的那個。若是說cost【n-2】大於cost【n-1】-1; 那麼咱們確定得選擇在這一天賣出,不能存到cost【n-1】再賣出。 而後每次賣出就改變比較的值,往前面比較。你可能會問爲何要改變。 由於cost【n-2】的狀態確定大於cost【n-1】-1,那麼再往前推一步, cost【n-2】-1確定大於cost【n-1】-2;因此保留cost【n-2】去與 cost【n-3】進行比較就能夠了。 咱們能夠先標記在哪一天賣出,最後進行一次O(n)的計算就能夠得出答案了。 **/ int main() { int n; while(~scanf("%d",&n)) { memset(gas,0,sizeof(gas)); memset(cost,0,sizeof(cost)); memset(flag,0,sizeof(flag)); for(int i=0; i<n; i++) scanf("%lld",&gas[i]); for(int i=0; i<n; i++) scanf("%lld",&cost[i]); flag[n-1]=1;///初始標記,最後一天確定賣出 int ans=cost[n-1];///轉移的價格 for(int i=n-2;i!=-1;i--) { if(ans-1>cost[i]) { ans--;///若是價值依舊大,那麼往前接着轉移 } else { ans=cost[i];///若是價值小的話,進行改變轉移值 flag[i]=1;///標記賣出,再往前轉移 } } ll sum,num; sum=0; num=0; for(int i=0;i<n;i++)///計算答案 { if(flag[i]) { sum+=(num+gas[i])*cost[i]; num=0; } else { num+=gas[i]; sum-=num; } } printf("%lld\n",sum); } return 0; }