題目鏈接:luogu P2938
題目
儘管奶牛天生謹慎,它們仍然在住房抵押信貸市場中大受打擊,現在它們準備在股市上碰碰運氣。貝西有內部消息,她知道 只股票在今後 天內的價格。
假設在一開始,她籌集了 元錢,那麼她該怎樣操作才能賺到最多的錢呢?貝西在每天可以買賣多隻股票,也可以多次買賣同一只股票,交易單位必須是整數,數量不限。舉一個牛市的例子:
假設貝西有 元本金,股票價格如下:
股票 | 今天的價格 | 明天的價格 | 後天的價格 |
---|---|---|---|
最賺錢的做法是:今天買入 股 張,到明天把它賣掉並且買入 股 張,在後天賣掉 股,這樣貝西就有 元了。
輸入
第一行:三個整數 , 和 , ; ;
第二行到第 行:第 行有 個整數: 到 ,表示第 種股票在第一天到最後一天的售價,對所有數據, , 。
輸出
單個整數:表示奶牛可以獲得的最大錢數,保證這個數不會超過
樣例輸入
2 3 10
10 15 15
13 11 20
樣例輸出
24
思路
這道題就是一道揹包。
我們對於每一個股票,我們可以在每一天對它進行個操作的其中一個:
- 不買
- 買完明天賣
- 買完第天賣
然後我們可以發現,第三種操作可以轉換成很多次第二種操作。比如,第一天買入第三天賣出其實等於第一天買入,第二天賣出,第二天又買入,第三天又賣出。
那麼這樣,就只有選和不選了。
然後我們知道股票可以買很多張的,所以這道題就是完全揹包了。
對於每兩天的間隔,我們都做一次完全揹包(即做次揹包),求出最多錢的那一次,就是答案了。
代碼
#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;
}