很有意思的dp
2026-09-16 22:52:28
发布于:广东
3阅读
0回复
0点赞
先说结论:不需要考虑跨多天持有纪念品,只需要考虑相邻两天的交易
为什么?
当我们获得了纪念品,它的结局就是1、第二天被卖掉或2、持有几天后被卖掉(后面要考)
但是我们发现,举个例子,第 1 天买,第 3 天卖。等价于:
1→2 卖出,再 2 买入,再 2→3 卖出,利润是一样的。所以我们可以把前一天的东西在后一天全部卖掉,然后再做完全背包购买第二天的物品,使其相对于第三天利润最大(如果利润为负数则不考虑),像前面举的例子,如果我们用第二天卖的钱再次购买了2,就相当于把2在手上持有了一天,后续再卖掉,实现了2、持有几天后被卖掉,如果有利润更高的买法但没买2,就相当于将2立马卖出了,实现了1、第二天被卖掉。
配合代码食用更佳:
#include <bits/stdc++.h>
using namespace std;
const int MAXM = 10005;
const int MAXT = 105;
const int MAXN = 105;
int price[MAXT][MAXN];
int dp[MAXM];
int main(){
int T, n, money;
cin >> T >> n >> money;
for(int i = 1; i <= T; i++){
for(int j = 1; j <= n; j++){
cin >> price[i][j];
}
}
for(int day = 1; day <= T-1; day++){
memset(dp, 0, sizeof(dp));
int today = day;
int tomorrow = day + 1;
for(int i = 1; i <= n; i++){
int now = price[today][i],next = price[tomorrow][i];
int profit = next - now;
if(profit <= 0) continue;
for(int j = now; j <= money; j++){
dp[j] = max(dp[j], dp[j - now] + profit);
}
}
money += dp[money];
}
cout << money << endl;
return 0;
}
这里空空如也

有帮助,赞一个