股 票 市 场 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 2≤S≤50 ; 2 ≤ D ≤ 10 2 ≤ D ≤ 10 2≤D≤10 ; 1 ≤ M ≤ 200000 1 ≤ M ≤ 200000 1≤M≤200000
第二行到第 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 1≤j≤D, 1 ≤ P i j ≤ 1000 1≤P_{i_j} ≤ 1000 1≤Pij≤1000。
输出
单个整数:表示奶牛可以获得的最大钱数,保证这个数不会超过 500000 500000 500000
样例输入
2 3 10
10 15 15
13 11 20
样例输出
24
思路
这道题就是一道背包。
我们对于每一个股票,我们可以在每一天对它进行
3
3
3个操作的其中一个:
- 不买
- 买完明天卖
- 买完第 i i i天卖
然后我们可以发现,第三种操作可以转换成很多次第二种操作。比如,第一天买入第三天卖出其实等于第一天买入,第二天卖出,第二天又买入,第三天又卖出。
那么这样,就只有选和不选了。
然后我们知道股票可以买很多张的,所以这道题就是完全背包了。
对于每两天的间隔,我们都做一次完全背包(即做 D − 1 D-1 D−1次背包),求出最多钱的那一次,就是答案了。
代码
#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;
}