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;
}
相关文章
相关标签/搜索