初态下你有 \(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);
}

相关文章: