luogu P2577午餐(动态规划)

【LuoguP2577】[ZJOI2005]午餐 题目链接 题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂。这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭。由于每个人的口味(以及胃口)不同,所以他们要吃的菜各有不同,打饭所要花费的时间是因人而异的。另外每个人吃饭的速度也不尽相同,所以吃饭花费的时间也是可能有所不同的。 THU ACM小组的吃饭计划是这样的:先把所有的人分成两队,并安排好... 阅读详情

https://www.luogu.org/problemnew/show/P2577

题解

这其实是一个背包问题的变形,如果只有一个窗口的话,对于排队打饭的时间是固定的,那么只要按照谁吃的慢谁先上就可以得出最优值。

这道题有两个窗口,贪心的方法还是一样的,但是需要考虑分配问题。
设dp[i][j][k]: 下标:前i个人在窗口1花了j的打饭时间,在窗口2花了k的打饭时间。值: 前i个人最小的用餐时间。

设打饭时间为a,吃饭时间为b。
状态转移方程很容易写出来:
考虑决策:

  1. 第i个人打饭+吃饭的时间被前i-1个人的总时间覆盖。
  2. 第i个人打饭+吃饭的时间不被前i-1个人的总时间覆盖。

在窗口1打饭
d p [ i ] [ j ] [ k ] = m i n ( d p [ i ] [ j ] [ k ] , m a x ( d p [ i − 1 ] [ j − a ] [ k ] , j + b ) ) dp[i][j][k] = min(dp[i][j][k], max(dp[i-1][j-a][k], j+b) ) dp[i][j][k]=min(dp[i][j][k],max(dp[i−1][j−a][k],j+b))

在窗口2打饭
d p [ i ] [ j ] [ k ] = m i n ( d p [ i ] [ j ] [ k ] , m a x ( d p [ i − 1 ] [ j ] [ k − a ] , j + b ) ) dp[i][j][k] = min(dp[i][j][k], max(dp[i-1][j][k-a], j+b) ) dp[i][j][k]=min(dp[i][j][k],max(dp[i−1][j][k−a],j+b))

但由于数据量是200*40000*40000,所以三维开不下。
对于这种两个有关联的变量,就要考虑用一个变量推出另一个变量。

注意前面一个队伍的情况,打饭时间是固定的!
所以对于前i个人的打饭时间是固定的!那么只要知道花在窗口1多少打饭时间,自然就可以知道花在窗口2的打饭时间了。
因此便省去了一维。

设dp[i][j]: 下标:前i个人在窗口1花了j的打饭时间。值: 前i个人最小的用餐时间。

状态转移方程:

在窗口1打饭
d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , m a x ( d p [ i − 1 ] [ j − a ] , j + b ) ) dp[i][j] = min(dp[i][j], max(dp[i-1][j-a],j+b)) dp[i][j]=min(dp[i][j],max(dp[i−1][j−a],j+b))
在窗口2打饭

sum[i]:前i个人打饭时间的前缀和。
sum[i]-j:前i个人在队伍2的打饭时间。
d p [ i ] [ j ] = m i n ( d p [ i ] [ j ] , m a x ( d p [ i − 1 ] [ j ] , s u m [ i ] − j + b ) ) dp[i][j] = min(dp[i][j], max(dp[i-1][j], sum[i]-j+b)) dp[i][j]=min(dp[i][j],max(dp[i−1][j],sum[i]−j+b))

代码

#include <bits/stdc++.h>
using namespace std;
#define FOR0(a,b) for(int i = a; i < b; ++i)
#define FORE(a,b) for(int i = a; i <= b; ++i)
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 200+5;
const int INF = 0x3f3f3f3f;

struct Peo {
	int da, eat;
	bool operator < (const Peo& rhs) const {
		return eat > rhs.eat;
	}
}a[maxn];
int dp[maxn][maxn*maxn],n, sum[maxn];
// 前i个人,在队伍1打饭耗时j 时总的最小用餐时间
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) {
		scanf("%d%d", &a[i].da, &a[i].eat);

	}
	sort(a+1,a+1+n);
	memset(dp, INF, sizeof dp);
	dp[0][0] = 0;

	for(int i = 1; i <= n; ++i)
		sum[i] = sum[i-1]+a[i].da;
	for(int i = 1; i <= n; ++i) {
		for(int j = sum[i]; j >= 0; --j) {
			// 排在队伍1
			if(j >= a[i].da)
				dp[i][j] = min(dp[i][j], max(dp[i-1][j-a[i].da], j+a[i].eat));
			// 两个决策: 前一个人吃完饭的时间是否覆盖第i个人,不覆盖
			// 排在队伍2
			dp[i][j] = min(dp[i][j], max(dp[i-1][j], sum[i]-j+a[i].eat));
		}
	}
	int ans = INF;
	for(int i = 0; i <= sum[n]; ++i)
		if(dp[n][i] < ans) ans = dp[n][i];
	printf("%d\n", ans);
	return 0;
}
C/C++排队打饭 C/C++排队打饭 题目描述 每天中午下课铃一打,同学们为了能尽早吃上饭,不要排那么长时间的队,都像狼一样冲向食堂,校领导看到这种情况很是担忧,因为学生们这样狂奔很危险,所以就要求必须等所有同学都来到食堂才能开始打饭,并且把排队打饭的顺序固定下来,这样谁都不用抢了。 学校里一共有N(1<=N<=100)个学生,每个学生打饭所需时间也是已知的,为了不让学生排队等得心烦,要求设计一个排队顺序使得所有学生的等待时间之和最小,等待时间为从开始排队到开始打饭所需的时间,所以第一个学生的等待时间为0。 为了 阅读详情

相关推荐

从零到一:Halcon手眼标定的实战避坑指南

本文详细解析了Halcon手眼标定的完整流程,重点介绍了Eye-in-Hand和Eye-to-Hand两种模式的实操技巧与常见陷阱。通过九点法、N点法等实战案例,提供硬件配置检查、数据采集策略及误差修正方案,帮助开发者提升机械臂与视觉系统的协同精度,适用于工业自动化领域的精准定位与抓取任务。

neovim7hacker的博客 234

洛谷 动态规划一日游 P2577、P1070、P2051

记 2018年3月19日 贼颓呢,一天就写了两道DP,还都不会写,这可GG。 动态规划真的难且有趣,算法题中动态规划占到了很大的比例,而且动态规划往往是辅助解决一些其他类型问题的基础,加深加强对动态规划问题的认识和训练非常有必要。 P2577 午餐 题意 题意见题目链接 题解 这道题目本质上是一道背包问题,是背包问题的变形,这道题不同的地方在于有两个背包。 因此,...

SUNSET 392

【机器人开发】四足机械狗(并联结构)URDF建模与Simscape仿真全流程解析

本文详细解析了四足机械狗(并联结构)从URDF建模到Simscape仿真的全流程开发。内容涵盖SolidWorks建模要点、URDF文件导出与优化、Matlab/Simscape环境搭建,以及并联机构特有的运动控制和步态规划实现,为机器人开发者提供了一套完整的解决方案。

weixin_30642561的博客 527

【做题记录】DP 杂题

P2577 [ZJOI2004]午餐 $\texttt{solution}$ 想到贪心: 吃饭慢的先打饭节约时间, 所以先将人按吃饭时间从大到小排序。 状态: \(f[i][j]\) 表示前 \(i\) 个人,在 \(1号\) 窗口打饭总时间 \(j\) ,最早吃完饭的时间。 我们可以发现 \(j+k\) 等于前 \(i\) 个人打饭总和( \(sum[i]\) ),\(k = sum(i)-...

EricQian的博客 179

一条龙开发指南:MCP AI Agent 理论+项目实战开发你的MCP Server

MCP(Model Connection Protocol)是Anthropic于2024年推出的AI模型连接协议,旨在为AI模型提供开放、通用的标准化接口,类似于“USB-C”接口,使AI模型能够无缝连接各种数据源和工具。MCP通过标准化协议解决了AI系统集成中的碎片化问题,提升了开发效率和系统可靠性。开发者可以通过简单的配置,快速接入不同的MCP Server,实现AI模型的多样化应用。MCP支持多种协议,如Stdio、SSE等,并通过JSON-RPC格式进行数据传输。文章还以腾讯云代码助手为例,展示了

杨不易呀 3045

AniME框架深度体验:用AI自动生成《修真小说》动画全流程记录

本文详细记录了使用开源多智能体框架AniME,结合其核心动画生成模型AniSora V3,将一段修真小说文本自动转化为风格统一动画视频的全流程实战。文章深入解析了从环境搭建、导演智能体任务分解,到多智能体协作生成分镜、角色、动画及最终合成的每一步操作与挑战,为AI驱动的长视频创作提供了宝贵的实践经验与流程优化思路。

ol789012345的博客 625

洛谷 P2577 午餐(贪心排序,DP)

题目大意: 已知一群学生分别有独立的排队打饭时间,以及吃饭时间。已知有两个窗口,学生可以在这两个窗口之中的一个排队,学生一旦打完饭就开始吃饭,问怎么安排学生在两个窗口之间排队可以让最后一个吃完饭的学生的时间尽可能的早。 解题思路: 首先,我们假设只有一个窗口的时候怎么排序是最优的,这里有一个重要的发现就是:当把学生的吃饭时间从大到小排序后再安排学生以这个顺序打饭是最优的。有了这一个重要的发现...

FrostMonarch的博客 310

ENVI5.6 自动化流程:GF系列卫星影像批处理与质量优化

本文详细介绍了如何利用ENVI5.6构建针对GF-2、GF-6、GF-7系列卫星影像的自动化批处理流水线。通过配置Batch Processing工具,实现从正射校正到图像融合的全流程批量处理,并分享参数设置、质量监控与故障排查的实战经验,旨在显著提升海量遥感影像的处理效率与成果质量。

efc1234567的博客 603

洛谷P2577 [ZJOI2005]午餐 打饭时间作为容量DP

P2577 [ZJOI2005]午餐 )逼着自己做DP 题意:   有n个人打饭,每个人都有打饭时间和吃饭时间。有两个打饭窗口,问如何安排可以使得总用时最少。 思路:   1)可以发现吃饭时间最长的要先打饭。(我也是看别人题解才知道)   2)然后就是对于前i个人,他不是在一号窗口打饭,就是在二号窗口打饭。所以用dp[i][j]表示前i个人,在一号窗口打饭j时间的总用时。因为dp[i]...

weixin_30773135的博客 205

Qwen2.5-Omni实战:5分钟搞定多模态AI模型本地部署(含Thinker-Talker架构解析)

本文详细介绍了Qwen2.5-Omni多模态AI模型的本地部署流程,包括硬件配置、环境准备和实战应用开发。特别解析了其创新的Thinker-Talker架构,该架构通过TMRoPE位置编码实现跨模态同步处理,大幅提升多模态任务效率。5分钟即可完成部署,适合开发者快速实现文本、图像和音频的联合处理。

weixin_29085865的博客 171

Agent应用实践之二十九 - 设计模式:人机协同

本章讲解了一种比较常见的设计模式:人机协同。通过一些场景举例,同时使用AgentScope本身自带的能力实现的人机协同模式,最后通过源码分析了AgentScope中如何实现。通过了解人机协同模式对于实际工程使用也是非常有用的。

代码让AI扣 305

luogu2577[ZJOI2005]午餐

题目链接 首先贪心,发现先把吃饭时间长的放在前面(证明略去) 如果吃饭时间相同,打饭时间少的放在前面 剩下部分一看就是一个背包,但直接开40000*40000爆空间和时间 考虑优化掉一维 用f[i][j] = k 表示前 i 个人在队伍 1 里正好花了 j 分钟的时候, 最早吃完的方法花了 k 分钟 这样就可以轻松过掉题目了 #include&lt;bits/stdc++.h&gt;...

LJC00118的博客 388

11、牛转录组分析的实用生物信息学流程

本文详细介绍了一套实用的牛转录组分析生物信息学流程,涵盖从数据提取、基因组索引生成、读取比对到单样本表达分析及差异表达分析的完整步骤。使用Angus和Brahman牛的RNA-seq数据作为示例,介绍了HTSEQ、featureCounts和StringTie等工具在基因表达计数中的应用,并结合edgeR和limma进行差异表达分析。文中提供了详细的命令行与R代码示例,包含常见问题解答与关键注意事项,帮助研究人员高效、准确地完成转录组数据分析。

ios99的博客 111

luogu P2577 [ZJOI2005]午餐 序列DP

我们先考虑只有一个窗口的情况。如果只有一个窗口,显然我们应该按照吃饭的时间进行排序,按这个顺序先后打饭吃饭即可。因为窗口打饭时间的和是一定的,我们越让吃饭快的人靠后,最后的结束时间就可能更早。 那么对于两个窗口,我们依旧将人按照吃饭快慢排序。现在得到了一个序列,我们考虑序列DP。用f[i][t]表示,i及i以前的学生都吃完饭,并且一号窗口打了t时间的饭,的最后一个吃完饭的人的结束时间(两个窗口的...

weixin_34212189的博客 124

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Luogu P2577 [ZJOI2005]午餐

一道贪心+类背包DP的好题 首先发现一个十分显然的性质,没有这个性质整道题目都难以下手: 无论两队的顺序如何,总是让吃饭慢的人先排队 这是一个很显然的贪心,因为如果让吃饭慢的排在后面要更多的时间至少没有这样优 因此我们先按吃饭时间从大到小sort一下 然后我们发现这是一个类01背包的DP,只不过这里的状态要么是01,要么是10(即要么在1队,要么在2队) 然后这种东西都有一些很神奇的性质...

weixin_30954265的博客 140

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

luogu 2577 [ZJOI2005]午餐 贪心+dp

Code: #include <bits/stdc++.h> #define N 201 #define setIO(s) freopen(s".in","r",stdin) using namespace std; struct P { int a,b; P(int a=0,int b=0):a(a),b(b){} }s...

weixin_30419799的博客 165

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

[Luogu P2577] [BZOJ 1899] [ZJOI2005]午餐

洛谷传送门 BZOJ传送门 题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行NNN人来到了著名的十食堂。这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭。由于每个人的口味(以及胃口)不同,所以他们要吃的菜各有不同,打饭所要花费的时间是因人而异的。另外每个人吃饭的速度也不尽相同,所以吃饭花费的时间也是可能有所不同的。 THU ACM小组的吃饭计划是这样的:先把所有的人分成两...

LPA的博客 241

LUOGU P2577 [ZJOI2005]午餐

传送门 解题思路 贪心+dp。首先一定是让吃的慢的先吃这是很显然的,所以按照b[i]排一遍序,然后考虑dp,设dp[i][j]表示前i个人第一个队伍的排队时间为j的最小时间,转移比较容易理解 #include<iostream> #include<cstdio> #include<cstring> #include<cstd...

weixin_30345055的博客 103

Luogu 2577[ZJOI2005]午餐 - 动态规划

Solution 啊。。。 我太菜了唔 不看题解是不可能的, 这辈子都不可能的。 首先一个队伍中排队轮到某个人的时间是递增的, 又要加上吃饭时间, 所以只能使吃饭时间递减, 才能满足最优,于是以吃饭时间为关键字排序 然后定义数组 $f[i][j]$ 为前$i$个,第一个队伍要排$j$分钟时, 前$i$个人最晚吃完饭的时间。我们还可以很快的算出第二个队伍要排 $sum[i] - j$分...

weixin_30337251的博客 91

luogu2577/bzoj1899 午餐 (贪心+dp)

首先,应该尽量让吃饭慢的排在前面,先按这个排个序 然后再来决定每个人到底去哪边 设f[i][j]是做到了第i个人,然后1号窗口目前的总排队时间是j,目前的最大总时间 有这个i和j的话,再预处理出前i个人的排队总时间sum[i],可以知道在2号窗口的排队时间是sum[i]-j 拿着两个去更新答案就行了 1 #include<bits/stdc++.h> 2 #defi...

weixin_30750335的博客 118

「ZJOI 2005」午餐「DP」

题目传送门 题解 贪心+DP\text{DP}DP,思想巧妙。 首先确定先后顺序,不确定站在哪边。贪心策略是按吃饭时间从大到小排序,证明如下: 设按某个顺序站,第AAA个人打饭时间为aaa,吃饭时间为bbb;第B(A&amp;amp;lt;B)B(A&amp;amp;lt;B)B(A&amp;lt;B)人打饭时间为ccc,吃饭时间为ddd;b&amp;amp;lt;db &amp;amp;lt; db&amp;lt;d t1=max(a+b,a...

_Gion 289

NOIp2019前dp专题题解1.0

luogu1373 小a和uim之大逃离:暴力dp的话就是记\(dp_{i,j,p,q,0/1}\)表示当前在\((i,j)\),第一/二个人的数模\(k+1\),且当前轮到了第一/二个人的方案数。优化的话考虑答案统计\(p=q\)的方案数,那么可以把那两维省掉直接记两者差值,时间\(O(NMK)\) luogu1220 关路灯:注意到每次所有关掉的灯必然是一个连续区间,且人一定站在区间...

adfa4535的博客 340

P2577-午餐

1 #include <bits/stdc++.h> 2 #define _for(i,a,b) for(int i = (a);i < b;i ++) 3 #define _rep(i,a,b) for(int i = (a);i > b;i --) 4 #define INF 0x3f3f3f3f 5 typedef long long ...

weixin_30276935的博客 105

深入 `numpy.core.multiarray`:从C扩展编译到导入失败的底层原理与修复

本文深入解析NumPy核心模块`numpy.core.multiarray`的C扩展编译原理与导入失败问题。从Python与C的混合架构出发,详细分析动态链接过程中的ABI兼容性、运行时依赖等关键因素,并提供跨平台(Linux/macOS/Windows)的解决方案和高级调试技巧,帮助开发者彻底解决NumPy导入问题。

weixin_30836759的博客 322

【动态规划】 背包问题整理

【动态规划】 背包问题整理 背包问题02 题目类型描述: 给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高(from 百度百科)。 具象理解: 假设背包总容量top_weight为10,现共有四样物品(每样各一个),他们的重量和价格分别为: 抽象建模:        我们可以构建一个...

findover的博客 342
上一篇: codeforces 1153D Serval and Rooted Tree(树形dp+贪心)
下一篇: 【gym 101606H】Hiking (队列模拟)
Link_Ray
博客等级 码龄9年 44粉丝 156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值