股票市场Stock Market

股 票 市 场 S t o c k   M a r k e t 股票市场Stock\ Market Stock Market

题目链接:luogu P2938

题目

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

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

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

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

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

输入

第一行:三个整数 S S S D D D M M M 2 ≤ S ≤ 50 2 ≤ S ≤ 50 2S50 ; 2 ≤ D ≤ 10 2 ≤ D ≤ 10 2D10 ; 1 ≤ M ≤ 200000 1 ≤ M ≤ 200000 1M200000

第二行到第 S + 1 S + 1 S+1 行:第 i + 1 i + 1 i+1 行有 D D D 个整数: P i 1 P_{i_1} Pi1 P i D P_{i_D} PiD,表示第 i i i 种股票在第一天到最后一天的售价,对所有数据, 1 ≤ j ≤ D 1 ≤ j ≤ D 1jD 1 ≤ P i j ≤ 1000 1≤P_{i_j} ≤ 1000 1Pij1000

输出

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

样例输入

2 3 10 
10 15 15 
13 11 20 

样例输出

24 

思路

这道题就是一道背包。
我们对于每一个股票,我们可以在每一天对它进行 3 3 3个操作的其中一个:

  1. 不买
  2. 买完明天卖
  3. 买完第 i i i天卖

然后我们可以发现,第三种操作可以转换成很多次第二种操作。比如,第一天买入第三天卖出其实等于第一天买入,第二天卖出,第二天又买入,第三天又卖出。
那么这样,就只有选和不选了。
然后我们知道股票可以买很多张的,所以这道题就是完全背包了。

对于每两天的间隔,我们都做一次完全背包(即做 D − 1 D-1 D1次背包),求出最多钱的那一次,就是答案了。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define rr register

using namespace std;

int t, n, m, a[51][11], f[500001];

int main() {
	scanf("%d %d %d", &t, &n, &m);//输入
	for (int i = 1; i <= t; i++)
		for (int j = 1; j <= n; j++)
			scanf("%d", &a[i][j]);//输入
	
	for (int i = 2; i <= n; i++) {
		memset(f, 0, sizeof(f));//初始化
		int maxn = 0;
		for (int j = 1; j <= t; j++) {
			for (rr int k = a[j][i - 1]; k <= m; k++) {
				f[k] = max(f[k], f[k - a[j][i - 1]] - a[j][i - 1] + a[j][i]);//动态转移方程
				maxn = max(maxn, f[k]);//记录最大值
			}
		}
		m += maxn;//现有的钱为之前的钱加上今天赚的钱
	}
	
	printf("%d", m);//输出
	
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值