2018 FJUT ACM校賽L題 外傳:魔王打工記(三)

外傳:魔王打工記(三)

TimeLimit:1000MS  MemoryLimit:128MB
64-bit integer IO format: %lld
 
Problem Description

    靠着小明的朝五晚九地經營共享單車,魔王堡的總算熬過了這一個月。可是好景不長,共享單車市場競爭的太激烈,小明的公司已經開始虧損了,再這麼下去吃棗藥丸。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

 

Input

單組數據,第一行是一個整數n表明天數orm

接下來一行 有n個數字  a1,a2,a3……an  表明天天收穫上來的蔬菜的數量blog

再接下一行 有n個數 字 b1,b2,b3……bn  表明蔬菜天天的價格 ip

1<=n<=5*105數據分析

0<ai,bi<=105

Output

輸出一個整數,表明若是採起最優策略來賣菜,那麼n天結束後Home_W最多能賺到錢的數量.

注意賣的時候必須賣光,不能留任何蔬菜

SampleInput
8
7 9 8 3 5 5 6 9
4 9 4 3 3 7 4 5 
SampleOutput
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;
}
相關文章
相關標籤/搜索