初态下你有 \(m\) 元钱,有 \(n\) 个股票,你有超能力可以知道未来 \(T\) 天它们的价格,现在空仓,第 \(T\) 天结束后清仓,求能拥有的最多的钱数。\(T \leq 100, n \leq 100, m \leq 10^3\),任何时候钱数不超过 \(10^4\)
Solution
我们把问题转化成每天持有哪些物品的多重背包,那么持有一个物品占用的体积就是钱数,价值就是这一天能赚的钱,于是设 \(f[i][j][k]\) 表示前 \(i\) 天,考虑了前 \(j\) 个股票,剩余钱数为 \(k\) 的最大收益,则
\[f[i][j][k]=\max(f[i][j][k],f[i][j-1][k+p_{i,j}]+p_{i+1,j}-p_{i,j})
\]
其中 \(p_{i,j}\) 表示第 \(i\) 天股票 \(j\) 的净值
暴力转移即可
#include <bits/stdc++.h>
using namespace std;
int f[20005],g[20005],p[105][105],n,m,t;
void sh(int &x,int y) {x=max(x,y);}
signed main() {
ios::sync_with_stdio(false);
cin>>t>>n>>m;
for(int i=1;i<=t;i++) {
for(int j=1;j<=n;j++) {
cin>>p[i][j];
}
}
for(int i=1;i<=t;i++) {
if(i>1) m=*max_element(f,f+10001);
memset(f,-0x3f,sizeof f);
f[m]=m;
for(int j=1;j<=n;j++) {
for(int k=1e4;k>=0;k--) {
f[k]=max(f[k],f[k+p[i][j]]+p[i+1][j]-p[i][j]);
}
}
}
cout<<*max_element(f,f+10001);
}