题目链接
题目大意
已知 N N N 个商品未来 T T T 天的价格,现在手上有 M M M 元钱,求 T T T 天后最多能获得多少钱。
思路分析
首先,持有一个物品等同于每天买下这个物品,第二天卖出后再迅速买入,第三天卖出后再迅速买入……
所以我们可以从第 1 1 1 天遍历至第 T − 1 T-1 T−1 天,每天对 N N N 个商品进行一次完全背包,对钱数 M M M 进行更新。
我们以物品当日的价格
p
i
,
j
p_{i,j}
pi,j 作为重量,赚到的钱
p
i
+
1
,
j
−
p
i
,
j
p_{i+1,j}-p_{i,j}
pi+1,j−pi,j 为价值,所以状态转移方程为
d
p
(
k
)
=
max
(
d
p
(
k
)
,
d
p
(
k
−
p
i
,
j
)
+
p
i
+
1
,
j
−
p
i
,
j
)
dp(k)=\max(dp(k),dp(k-p_{i,j})+p_{i+1,j}-p_{i,j})
dp(k)=max(dp(k),dp(k−pi,j)+pi+1,j−pi,j)
代码
#include<bits/stdc++.h>
using namespace std;
const int N=105,M=1e4+10;
int t,n,m;
int p[N][N],dp[M];
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",&p[i][j]);
}
for (int i=1;i<t;++i){
memset(dp,0,sizeof dp);
for (int j=1;j<=n;++j){
for (int k=p[i][j];k<=m;++k) dp[k]=max(dp[k],dp[k-p[i][j]]+p[i+1][j]-p[i][j]);
//完全背包模板,买入一个商品此日能赚到 p[i+1][j]-p[i][j]
}
m+=dp[m];//因为获得的钱可以再用于交易,所以每天要更新 m
}
printf("%d",m);
return 0;
}