GalaxyOJ-774 (dp)

题目

Problem Description

从前有个小女孩,她很喜欢买股票。

股市一共开放n天,小女孩初始有m元,并且股市只有一支股票,现在小女孩通过水晶球得到未来n天的股票行情。

请问小女孩在第n天股市关门时最多能有多少钱。

下面介绍股市规则:

股市有一个固定的手续费F,每次买入之前或者卖出之后都要扣除F元。如果买入之前或者卖出之后现金不足F元则交易失败,不能买入或卖出。

股市中,小女孩只能购买整数份额的股票。

在第n天,小女孩操作完她的股票后股市才会关闭,就是说,你可以认为n天内都能买卖股票。

Input

第一行给出n,m,F,意义如题意所示。

接下来n行给出股市中唯一的一支股票在第i天的价格pi。

对于100%的数据 1<=n,m,F,pi <=100000

Output

你需要输出一个整数,代表小女孩第n天股市关闭后她手头上的最大现金数。

Sample Input

10000 1
4000
4004
4002

Sample Output

10006

分析

可以看出,每一天的股票,要卖的话就卖光最好,要买的话就买完(买到不能买)最好。
于是用两个东西存下每天的两种状态:(当天卖光所有股票剩下最多的钱数 以及 当天能持有的最多股票数),这都可以由前一天的这两点推出来。

程序

#include <cstdio>
#include <algorithm>
using namespace std;
long long n,m,p,F,x,y,f[100005],g[100005],c[100005];

int main(){
    scanf("%lld%lld%lld",&n,&m,&F);
    f[0]=m,g[0]=m;
    for (int i=1; i<=n; i++){
        scanf("%d",&p);
        f[i]=f[i-1],g[i]=g[i-1],c[i]=c[i-1];

        //卖股票 
        if (g[i-1]+c[i-1]*p>=F) f[i]=max(f[i],g[i-1]+c[i-1]*p-F);

        //买股票 
        if (f[i-1]>=F){
            x=(f[i-1]-F)/p,y=(f[i-1]-F)%p;
            if (c[i]<x) c[i]=x,g[i]=y;
            if (c[i]==x) g[i]=max(g[i],y);
        }
    }

    printf("%lld",f[n]);
}

提示

这题还有一种做法,用斜率优化做,可以想一想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值