• 2018 FJUT ACM校赛L题 外传:魔王打工记(三)


    外传:魔王打工记(三)

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

        靠着小明的朝五晚九地经营共享单车,魔王堡的总算熬过了这一个月。但是好景不长,共享单车市场竞争的太激烈,小明的公司已经开始亏损了,再这么下去吃枣药丸。

    统计局的工资可能都不够亏的。为保住自己裤衩不被当掉,Home_W正苦苦思索着策略,这时网上突然出现了阿里巴巴用区块链养猪的新闻,Home_W看到现在农业这么火,灵机一动,决定辞掉统计局的工作,回农村种地,用大数据分析和人工智能搞生态农业。

    现在Home_W要下乡种地n天,每天他都可以从地中收获到a[i]的蔬菜。同时第i天蔬菜的价格为b[i]。

    Home_W 有一个发大财的心,所以他可能不会立即卖掉刚收获上来的蔬菜,而是会屯几天的菜,等到价格高了再一次性清仓全部卖掉。

    但是每单位蔬菜每屯一天要花费1的电费用于制冷,比如,若单位电费为1,第1、2、3天得到蔬菜分别是3,2,1 那么把这些蔬菜屯到第4天再卖,要花费3*3+2*2+1*1=14电费。我们伟大Home_W 大魔王用大数据技术和魔力的组合完美预测出了这n天中,每天他能收获的蔬菜数量和蔬菜每天的价格。于是他采

    取了最优策策略来卖菜,那么n天结束后他最多能赚到多少钱?

    Input

    单组数据,第一行是一个整数n代表天数

    接下来一行 有n个数字  a1,a2,a3……an  代表每天收获上来的蔬菜的数量

    再接下一行 有n个数 字 b1,b2,b3……bn  代表蔬菜每天的价格 

    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
    ",sum);
        }
        return 0;
    }
  • 相关阅读:
    第一次实验
    pta12
    《暗时间》读书笔记
    案例分析
    软件工程第二次作业
    阅读任务
    20210311_软工_准备工作
    学习总结
    第十四周学习总结&实验报告
    第十三周课程总结
  • 原文地址:https://www.cnblogs.com/qq136155330/p/9053999.html
Copyright © 2020-2023  润新知