#(完全背包的转化)洛谷背包问题P2938 [USACO09FEB]股票市场Stock Market(提高+/省选-)...

题目描述

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

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

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

股票今天的价格明天的价格后天的价格
AA101515
BB131120

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

输入格式

第一行:三个整数 S, D 和 M,2 ≤ S ≤ 502S50 ; 2 ≤ D ≤ 102D10 ; 1 ≤ M ≤ 2000001M200000

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

输出格式

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

题目描述

Despite their innate prudence, the cows took a beating in the home mortgage market and now are trying their hand at stocks. Happily, Bessie is prescient and knows not only today's S (2 <= S <= 50) stock prices but also the future stock prices for a total of D days (2 <= D <= 10).

Given the matrix of current and future stock prices on various days (1 <= PR_sd <= 1,000) and an initial M (1 <= M <= 200,000) units of money, determine an optimal buying and selling strategy in order to maximize the gain realized by selling stock on the final day. Shares must be purchased in integer multiples, and you need not spend all the money (or any money). It is guaranteed that you will not be able to earn a profit of more than 500,000 units of money.

Consider the example below of a bull (i.e., improving) market, the kind Bessie likes most. In this case, S=2 stocks and D=3 days. The cows have 10 units of money to invest.

|Stock|Today's price| Tomorrow's price| | Two days hence Stock | | | :-----------: | :-----------: | :-----------: | :-----------: | | AA | 10 | 15 | 15 | |BB | 13| 11|20 |

If money is to be made, the cows must purchase stock 1 on day 1. Selling stock 1 on day 2 and quickly buying stock 2 yields 4 money in the bank and one share of 2. Selling stock 2 on the final day brings in 20 money for a total of 24 money when the 20 is added to the bank.

输入格式

* Line 1: Three space-separated integers: S, D, and M

* Lines 2..S+1: Line s+1 contains the D prices for stock s on days 1..D: PR_sd

输出格式

* Line 1: The maximum amount of money possible to have after selling on day D.

输入输出样例

输入 #1复制
2 3 10 
10 15 15 
13 11 20 
输出 #1复制
24 
分析:
难点一:问题的转化
对于最后要求我们最大化利润,我们可以直接最大化每一天的利润,最后输出即可。这样,可以以每天的利润变动为状态进行DP
然后这样问题就转化成为最大化每一天的利润了,而且每天可以购进多只股票,而每只股票又可以多次购买,考虑每一天的情况,可以想到对于每天的利润变动,我们只需要对当天的所有股票来一次完全背包,
就可以了。
难点二:如何模拟利润的更动?
如果要维护当天的股票(不卖),可以看成是先卖出,在买入,再原利润的基础上更新一下利润差就可以了。
对于第i天第x支股票,有两种选择:买或者不买
假设f[i]存储投资i元时的最大价值,可以得到状态转移方程 f[i]=max{f[i],f[i-a[j][k-1]]+a[j][k]-a[j][k-1]} 也就是说不买直接保留,如果要买那么就等于购入它的余下资金所能产生的最大效益,减去昨日
的购入成本,再加上今天所拥有的的价值。
代码如下:

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int a[61][21],f[500005];
int main()
{
int s,d,m;
scanf("%d%d%d",&s,&d,&m);
for(int i=1;i<=s;i++)
{
for(int j=1;j<=d;j++)
{
scanf("%d",&a[i][j]);
}
}//以上不需要解释,a[i][j]存储第i支股票在第j天所拥有的价值
for(int k=2;k<=d;k++)//dp的阶段:天数
{
memset(f,0,sizeof(f));//每天都作为一个阶段,需要进行一次完全背包,求出当前天数
//下前一个状态转移过来的最大值
int maxx=0;//初始化最大价值
for(int i=1;i<=s;i++)//便利当天的所有股票
{
for(int j=a[i][k-1];j<=m;j++)//每次循环到前一天当前位置的股票交易价格。
{//j维护的是背包大小,因为是完全背包,所以正序便利
f[j]=max(f[j],f[j-a[i][k-1]]+a[i][k]-a[i][k-1]);//第一种情况是不买,第二种就是买:要价格减去买入所花的钱再加上今天和昨天的价格差,因为如果不卖出相当于卖出再买入
maxx=max(f[j],maxx);//取出一天股票的最大值
}
}
m+=maxx;//累加收益!
//注意,每天所获得的的效益是可以投资到下一天的计算中去的!
//也就是说当前天的最大价值(股票)可以直接全部出售
}
printf("%d",m);
return 0;
}

转载于:https://www.cnblogs.com/little-cute-hjr/p/11398954.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值