NC14704 美味菜肴
题目
题目描述
小明是个大厨,早上起来他开始一天的工作。他所在的餐厅每天早上都会买好 件食材(每种食材的数量可以视为无限),小明从到达餐厅开始就连续工作 时间。每道菜肴的制作需要特定的一种食材以及一段时间,但是食材一旦放久就不新鲜了,菜的美味值会降低。第 道菜肴有三个属性 , 是该菜肴的美味值, 是该菜肴所选食材不新鲜的速率,如果在第 时刻完成第 道菜则美味值为:,完成这道菜需要 的时间。小明希望在这 时间内能做出菜肴使得总美味值最大,所以小明求助于你。
输入描述
第1行输入三个整数 ,分别代表食材种类,菜肴种类和工作时间。
第2行输入 个整数 ,代表第 个食材不新鲜的速率。
接下来的m行,每行输入三个整数 ,分别代表第 道菜肴需要的食材编号,菜肴的美味值,完成时间。
数据保证: ,其他值均 ,美味值必须通过完整做出菜肴得到,数据保证在规定时间内至少能完整做出1道菜肴。
输出描述
输出一行,一个整数,表示最大总美味值。
示例1
输入
1 1 74 2 1 502 47
输出
408
示例2
输入
2 2 10 2 1 1 100 8 2 50 3
输出
84
备注
最大总美味值可能为负。
题解
知识点:贪心,背包dp。
注意到贡献是会被选择顺序影响,有后效性,不能直接dp。尝试用排序找到最优相对位置消除后效性。假设A菜先做比B菜先做更好,交换后其他菜的贡献不变,因此可以有如下邻项交换证明:
注意到最终排序结果由自身属性决定,因此可以以此贪心排序消除后效性。
随后就是个普通的01背包,注意至少要做一个菜,因此要初始化负无穷,避免一个菜都不选的情况,因此最后也要遍历区间 找最大值。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; ll b[57]; struct node { ll a, b, c; }cai[57]; ll dp[1000007]; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n, m, t; cin >> n >> m >> t; for (int i = 1;i <= n;i++) cin >> b[i]; for (int i = 1;i <= m;i++) cin >> cai[i].b >> cai[i].a >> cai[i].c, cai[i].b = b[cai[i].b]; ///由于时间会导致美味度变化,所以做菜顺序有后效性,因此贪心排序为最优顺序 sort(cai + 1, cai + m + 1, [&](node A, node B) {return A.b * B.c >= B.b * A.c;}); memset(dp, -0x3f, sizeof(dp));///因为不能不做,所以不放空气 dp[0] = 0; for (int i = 1;i <= m;i++) { for (int j = t;j >= cai[i].c;j--) {///不是完全背包 dp[j] = max(dp[j], dp[j - cai[i].c] + cai[i].a - j * cai[i].b); } } ll ans = -1e18; for (int i = 1;i <= t;i++) ans = max(ans, dp[i]);///i≠0 cout << ans << '\n'; return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/16581603.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧