• 【luogu P2938股票市场】题解


    股票市场

    题目描述

    尽管奶牛天生谨慎,它们仍然在住房抵押信贷市场中大受打击,现在它们准备在股市上碰碰运气。贝西有内部消息,她知道 S 只股票在今后 D 天内的价格。

    假设在一开始,她筹集了 M 元钱,那么她该怎样操作才能赚到最多的钱呢?贝西在每天可以买卖多只股票,也可以多次买卖同一只股票,交易单位必须是整数,数量不限。举一个牛市的例子:

    假设贝西有 10 元本金,股票价格如下:

    股票今天的价格明天的价格后天的价格
    A
    10 15 15
    B 13 11 20

    最赚钱的做法是:今天买入 A 股 1 张,到明天把它卖掉并且买入 B 股 1 张,在后天卖掉 B股,这样贝西就有 24 元了。

    输入格式

    第一行:三个整数 S, D 和 M,2 ≤ S ≤ 502 ≤ D ≤ 10 ; 1 ≤ M ≤ 200000

    第二行到第 S + 1 行:第 i + 1 行有 D 个整数:Pi;1 到 Pi;D,表示第 i 种股票在第一天到最后一天的售价,对所有1 ≤ j ≤ D1 ≤ Pi;j ≤ 1000

    输出格式

    单个整数:表示奶牛可以获得的最大钱数,保证这个数不会超过 500000

    输入输出样例

    输入 #1
    2 3 10 
    10 15 15 
    13 11 20 
    
    输出 #1
    24 

    题目有以下特殊性质,应当好好利用。
    1. 每次交易的股票数量不限
    2. 一种股票可以连续持有的数量不限。
    3. 最终的答案比较小。

    此外,我们在看看每天对于每种股票有哪些操作。
    1. 买
    2. 卖
    3. 买了再卖

    好,我们现在开始分析问题,如果只有一种股票,若何考虑?
    显然,(在股价连续上升的情况下)肯定选择第一天买,最后一天卖出。

    假如说第一天为第 i 天,最后一天为第 k 天。
    考虑一下下面一种情况,你或许会有所启发。

    假如到了k-1天,你发现如果这一天,你把你的股票卖了,你会赚到钱。
    你首先最大化了当天的收益
    于是你选择把股票卖了,但是你拥有预知未来的能力,你发现,如果你再把股票买回来,放到第k天卖,你会有额外的收益。
    于是你为了第k天钱更多,又把你的收益拿来买股票,换取第k天最大化收益。

    也就是说,当第k天时,用第k-1天最大化的收益买股票(或者不买)可以得到第k天的最大化收益

    也许你早就看出来了,这道题的本质是一个背包,因为数量无限,所以是个完全背包。
    再看看题目告诉我们的,最终的答案,也就是最大化收益比较小,那就可以把前一天最大化收益做成背包的上限。
    最大化当前的收益。
    最后可以套完全背包的模板了 ~打板子使我快乐~

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define R register int
    #define max(x,y) (x>y?x:y)
    using namespace std;
    int s,d,m,ma;
    int a[20][100],f[550000];
    inline void read(int &x){
        x=0;
        char ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    }
    int main()
    {
        read(s),read(d),read(m);
        for(R i=1;i<=s;i++)
            for(R j=1;j<=d;j++) 
                read(a[j][i]);
        for(R k=2;k<=d;k++){
            memset(f,0,sizeof(f));
            ma=0;
            for(R i=1;i<=s;i++)//此时m为前一天的最大化收益
                for(R j=a[k-1][i];j<=m;j++){//完全背包和01背包,仅仅在循环的顺序上有所差异
                    f[j]=max(f[j],f[j-a[k-1][i]]+a[k][i]-a[k-1][i]);//因为前一天有钱,可以买,放到这一天来卖。差价为增加的收益。
                    ma=max(ma,f[j]);//最大化收益    
                }
            m+=ma;//这是m为当天的最大化收益
        }
        printf("%d",m);
    }
  • 相关阅读:
    codeforces 1065F Up and Down the Tree
    初探莫比乌斯反演
    IOI2008 island
    miller——rabin判断素数
    NOIP2018游记
    NP是什么意思?
    word2016如何英汉互译
    2.1数字图像化
    Windows程序内部运行机制
    2.2图像灰度直方图
  • 原文地址:https://www.cnblogs.com/quitter/p/11722969.html
Copyright © 2020-2023  润新知