当前位置: 首页 > news >正文

【洛谷P1417】烹调方案 题解

题目大意

一共有 nnn 件食材,每件食材有三个属性,aia_iaibib_ibicic_ici,如果在 ttt 时刻完成第 iii 样食材则得到 ai−t×bia_i-t\times b_iait×bi 的美味指数,用第 iii 件食材做饭要花去 cic_ici 的时间。
需要设计烹调方案使得在TTT的时间内美味指数最大并输出。

数据范围及约定

  • 对于 40%40\%40% 的数据 1≤n≤101 \le n \le 101n10
  • 对于 100%100\%100% 的数据 1≤n≤501 \le n \le 501n50

所有数字均小于 10510^5105

暴力想法

首先我们可以观察到,若不考虑烹饪顺序,或是已知顺序的情况下,求解是很简单的:只需要使用复杂度O(n^2)的01背包进行dp即可

(如果不知道01背包,强烈建议跳转主页学习)

注意到前40%数据的N很小,我们便可以直接暴力枚举菜品的全排列,进行dp即可。

想明白后,我们稍加计算,就会发现:

超时辣!

时间复杂度O(n22n)O(n^22^n)O(n22n)过不了哒!(理论上超3e8次运算,数据很水就当我没说)

正解

其实刚刚的想法已经比较接近正解了。我们来看看上面的做法能怎么优化。

对于后半部分,可以基本确定是没有优化空间的——首先dp是必做,其次就算能将dp优化到O(nlogn)O(nlogn)O(nlogn)甚至O(n)O(n)O(n),大数据依旧是过不了的。

于是我们考虑如何排列烹饪顺序

首先可以观察到一个性质:如果交换相邻两个菜品的烹饪顺序,对前后菜品产生的贡献是没有影响的,因为交换后此前烹饪的总时间不变!

也就是说,如果存在菜品A优于B(即先烹饪A价值更大)、B优于C,则一定有A优于C!

接下来我们开始推理每种菜品的应有顺序。

假设有两个相邻的菜品序号为 i,ji,ji,j ,之前所用的总时间为TTT

根据题意可得,若先烹饪iii号菜品,得到的价值一共是:

w1=(ai−bi×(T+ci))+(aj−bj×(T+ci+cj))w_1=(a_i-b_i×(T+c_i))+(a_j-b_j×(T+c_i+c_j))w1=(aibi×(T+ci))+(ajbj×(T+ci+cj))
=ai+aj−T×(bi+bj)−bi×ci−bj×ci−bj×cj=a_i+a_j-T×(b_i+b_j)-b_i×c_i-b_j×c_i-b_j×c_j=ai+ajT×(bi+bj)bi×cibj×cibj×cj

若先烹饪jjj号菜品,得到的价值一共是:

w2=(aj−bj×(T+cj))+(ai−bi×(T+cj+ci))w_2=(a_j-b_j×(T+c_j))+(a_i-b_i×(T+c_j+c_i))w2=(ajbj×(T+cj))+(aibi×(T+cj+ci))
=ai+aj−T×(bi+bj)−bi×ci−bi×cj−bj×cj=a_i+a_j-T×(b_i+b_j)-b_i×c_i-b_i×c_j-b_j×c_j=ai+ajT×(bi+bj)bi×cibi×cjbj×cj

显然,若先烹饪iii号更优,则有w1>w2w_1>w_2w1>w2

带入并化简两边,可以得到 −bj×ci>−bi×ci-b_j×c_i>-b_i×c_ibj×ci>bi×ci

即:若bj×ci<bi×cjb_j×c_i<b_i×c_jbj×ci<bi×cj,则先烹饪iii号菜品更优。

所以,我们可以先根据上述结论对数组排序,再做dp

时间复杂度O(nT)O(nT)O(nT)(毕竟nnn很小,排序时间可以不计)

AC代码

#include<bits/stdc++.h>
using namespace std;
#define For(i, j, k) for(int i = j; i <= k; i++)
#define dFor(i, j, k)for(int i = j; i >= k; i--)
#define MaxN 55
#define int long longstruct Node{int a, b, c;bool operator<(const Node x) const{		//重载运算符,按之前的结论排序return c * x.b < b * x.c;}
}a[MaxN];
int T, n;
int f[MaxN][100005];signed main()
{cin >> T >> n;For(i, 1, n) cin >> a[i].a;For(i, 1, n) cin >> a[i].b;For(i, 1, n) cin >> a[i].c;sort(a+1, a+n+1);int ans = 0;For(i, 1, n){For(j, 1, T){				//01背包,虽然没有降维优化awaf[i][j] = max(f[i][j], f[i-1][j]);if(j >= a[i].c){f[i][j] = max(f[i][j], f[i-1][j-a[i].c] + a[i].a-a[i].b*j);}ans = max(ans, f[i][j]);}}cout << ans << endl;return 0;
}

总结

思维难度相对较高,主要在于推理传递性和排序规则

类似的题目还有P1060国王游戏等,可以练习

最后,制作实在不易。如果你喜欢这篇文章,可以点个免费的关注和免费的赞

我们下期再见!

http://www.xdnf.cn/news/1146259.html

相关文章:

  • SQL注入基础尝试
  • 71 模块编程之新增一个字符设备
  • ArcGIS Pro+PS 实现地形渲染效果图
  • 上网行为管理-web认证服务
  • 【C++基础】--多态
  • ThreadLocal 在 Spring 与数据库交互中的应用笔记
  • 北京-4年功能测试2年空窗-报培训班学测开-第五十四天
  • Kubernetes Pod深度理解
  • 大模型格式
  • 外部DLL创建及使用
  • UVC for USBCamera in Android - 篇二
  • 腾讯 ChatBI 调研
  • 如何为“地方升学导向型”语校建模?Prompt 框架下的宇都宫日建工科专门学校解析(7 / 500)
  • Java HashMap高频面试题深度解析
  • 对于编码电机-520直流减速电机
  • 【AI News | 20250717】每日AI进展
  • 3.3 参数传递方式
  • 应用集成体系深度解析:从数据互通到流程协同
  • 20250718【顺着234回文链表做两题反转】Leetcodehot100之20692【直接过12明天吧】今天计划
  • Machine Learning HW2 report:语音辨识(Hongyi Lee)
  • 操作系统-处理机调度和死锁进程同步
  • 全球天气预报5天(经纬度版)免费API接口教程
  • HarmonyOS-ArkUI Web控件基础铺垫4--TCP协议- 断联-四次挥手解析
  • 70 gdb attach $pid, process 2021 is already traced by process 2019
  • postman接口测试,1个参数有好几个值的时候如何测试比较简单快速?
  • PPIO × Lemon AI:一键解锁全流程自动化开发能力
  • 【DataWhale】快乐学习大模型 | 202507,Task03笔记
  • 机械材料计算软件,快速核算重量
  • Python暑期学习笔记5
  • Excel导出实战:从入门到精通 - 构建专业级数据报表的完整指南