P5662 [CSP-J2019] 纪念品
DP 题。
容易发现一个物品如果持有多天,可以转换为每拿一天,就卖掉,如果明天还持有,再买回来即可。
为了方便,我们不妨叫它:长期持有定理。
定义 为购买第 件物品, 为提供预算, 表示第 天, 代表物品 ,第 天的价格, 表示提供 元预算能赚的钱,状态转移方程如下:
答案即为 。
解释一下原因。
前一项即今日不购买第 件物品,后一项我们拆开看:
- ,购买后剩的钱能买到的最大金额。
- ,购买它花费的钱。
- ,根据长期持有定理,我们在第二天卖出,不会影响答案。
输入时颠倒下标,使第 天第 种纪念品的价格变为第 种第 天纪念品的价格。
直接转移即可,时间复杂度 :
#include<bits/stdc++.h>
using namespace std;
int t, m, n, a[105][105], f[10005];
int main(){
cin >> t >> n >> m;
for(int i = 1; i <= t; i ++)
for(int j = 1; j <= n; j ++)
cin >> a[j][i];
for(int k = 1; k < t; k ++){//第 t 天做的事情没有用
for(int i = 0; i <= m; i ++) f[i] = 0;//清空
for(int i = 1; i <= n; i ++)
for(int j = a[i][k]; j <= m; j ++)//从 1 开始下标可能为负
f[j] = max(f[j], f[j - a[i][k]]- a[i][k] + a[i][k + 1] );//状态转移方程
m += f[m];//赚的钱拿走
}
cout << m;
return 0;
}
posted on 2024-12-22 20:57 zhangzirui66 阅读(37) 评论(0) 收藏 举报 来源