【P2577】 午餐
题目简述
THU ACM小组一行N个人去食堂吃饭,计划是这样的:先把所有的人分成两队,并安排好每队中各人的排列顺序,然后一号队伍到一号窗口去排队打饭,二号队伍到二号窗口去排队打饭。每个人打完饭后立刻开始吃,所有人都吃完饭后立刻集合去六教地下室进行下午的训练。
现在给定了每个人的打饭时间和吃饭时间,要求安排一种最佳的分队和排队方案使得所有人都吃完饭的时间尽量早。
假设THU ACM小组在时刻0到达十食堂,而且食堂里面没有其他吃饭的同学(只有打饭的师傅)。每个人必须而且只能被分在一个队伍里。两个窗口是并行操作互不影响的,而且每个人打饭的时间是和窗口无关的,打完饭之后立刻就开始吃饭,中间没有延迟。
现在给定N个人各自的打饭时间和吃饭时间,要求输出最佳方案下所有人吃完饭的时刻。
输入输出格式
输入格式:
第一行一个整数N,代表总共有N个人。
以下N行,每行两个整数 Ai,Bi。依次代表第i个人的打饭时间和吃饭时间。
输出格式:
一个整数T,代表所有人吃完饭的最早时刻。
说明
所有输入数据均为不超过200的正整数。
solution
一道比较难想的动态规划(只是对于本蒟蒻),这道题的大体思路是贪心+DP
贪心是将N个人按照Bi的顺序排序,吃饭时间长的人放到前面盛饭
首先简化问题,假定只有一个打饭窗口,且定义延后时间T,第i个人的延后时间记作T[i],则T[i]=max(eat[i] - Σ(i<j<=N)time[j] , 0)其中j∈Z,N为总人数,time[j]表示第j个人的打饭时间,eat[j],表示第j个人的吃饭时间。显然,最后的集合时间为Σ(1<=j<=N)time[j] + max{T[j] , j∈[1,N]}。
将人按照eat大小从大到小排序后,可以证明此时max{T[j] , j∈[1,N]}最小,因为任何顺序改变都会导致max{T[j] , j∈[1,N]}增加(或至少持平),而Σ(1<=j<=N)time[j]不会改变。所以将人按照eat大小从大到小排序后,最后集合时间最短。我们可以很容易地将此结论推广到两支队伍的情况,从而证明贪心的正确性。
然后进行DP
DP[i][j]表示i个人盛饭排队共耗时j时最少话费的总时间
得出状态转移方程
for(re int i=;i<=n;++i)//i表示当前第i个人
{
for(re int j=;j<=sum[i];++j)//j表示当前花费的等待时间
{
if(j>=stu[i].a)
DP[i][j]=min(DP[i][j],max(DP[i-][j-stu[i].a],j+stu[i].b));//第一个队列花费的时间由max(DP[i-1][j-stu[i].a],j+stu[i].b)转移而来
//DP[i-1][j-stu[i].a]表示除去第i个人的总时间,因为有可能前面i-1个人还没吃饭第i个人就吃完了(队伍最后离开的是前i-1个人)
//j+stu[i]表示第i个人排队吃饭的时间(队伍最后离开的是第i个人)
DP[i][j]=min(DP[i][j],max(DP[i-][j],sum[i]-j+stu[i].b));//i在第二个队列的情况
//同上,DP[i-1][j]表示第i个人影响不到前面人的等待总时间
//sum[i]是前i个人的等待时间总和
}
}
code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstring>
#define maxn 205
#define maxt 40010
#define re register
using namespace std;
int DP[maxn][maxt],sum[maxn],n;
struct POP{
int a,b;
}stu[maxn];
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
bool cmp(POP A,POP B)
{
return A.b>B.b;
}
int main()
{
n=read();
for(re int i=;i<=n;++i)
{
stu[i].a=read();
stu[i].b=read(); }
memset(DP,,sizeof(DP));
sort(stu+,stu+n+,cmp);
for(re int i=;i<=n;++i)
{
sum[i]=sum[i-]+stu[i].a;
}jiufftts
DP[][]=;
for(re int i=;i<=n;++i)
{
for(re int j=;j<=sum[i];++j)
{
if(j>=stu[i].a)
DP[i][j]=min(DP[i][j],max(DP[i-][j-stu[i].a],j+stu[i].b)); DP[i][j]=min(DP[i][j],max(DP[i-][j],sum[i]-j+stu[i].b));
}
}
int ans=;
for(re int i=;i<=sum[n];++i)
ans=min(ans,DP[n][i]);
printf("%d",ans);
return ;
}
【P2577】 午餐的更多相关文章
- 洛谷P2577 午餐【贪心】【线性dp】
题目:https://www.luogu.org/problemnew/show/P2577 题意:n个人每个人有一个打饭时间和吃饭时间,将他们分成两个队伍.每个人打到饭之后就马上去吃饭.问怎么安排可 ...
- 洛谷 [P2577] 午餐
DP + 贪心 我们发现,如果只有一个窗口,贪心即可解决,吃饭时间长的人一定要先打饭 有两个窗口的时候,这条性质依然满足,但是两个窗口如何分配,需要 01 背包 #include <iostre ...
- 洛谷P2577 午餐
题目链接 题意概述:有n个人,第i个人打饭消耗ai时间,离开后吃饭耗费bi时间,将n个人分成两队,合理分配人员使总时间最短并输出总时间. 我们把问题拆分为两个部分.首先是排列顺序,然后是怎么分到两个队 ...
- 洛谷P2577 [ZJOI2005]午餐 打饭时间作为容量DP
P2577 [ZJOI2005]午餐 )逼着自己做DP 题意: 有n个人打饭,每个人都有打饭时间和吃饭时间.有两个打饭窗口,问如何安排可以使得总用时最少. 思路: 1)可以发现吃饭时间最长的要先打饭. ...
- Luogu P2577 [ZJOI2005]午餐(dp)
P2577 [ZJOI2005]午餐 题面 题目描述 上午的训练结束了, \(THU \ ACM\) 小组集体去吃午餐,他们一行 \(N\) 人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时 ...
- P2577 [ZJOI2005]午餐 状压DP
题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...
- P2577 [ZJOI2005]午餐
题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...
- 【题解】洛谷P2577 [ZJOI2005] 午餐(DP+贪心)
次元传送门:洛谷P2577 思路 首先贪心是必须的 我们能感性地理解出吃饭慢的必须先吃饭(结合一下生活) 因此我们可以先按吃饭时间从大到小排序 然后就能自然地想到用f[i][j][k]表示前i个人在第 ...
- [洛谷P2577] [ZJOI2005]午餐
洛谷题目链接:[ZJOI2005]午餐 题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的 ...
- 【洛谷P2577】[ZJOI2005]午餐
午餐 题目链接 DP题都辣么毒瘤的么.. 首先,看一下题解 我们就有了思路: 贪心:显然,让吃饭慢的先打饭,sort一遍(证明?不存在的.. DP:f[i][j][k]表示前i个人,窗口1的打饭时间为 ...
随机推荐
- JavaSE:八种基本数据类型
变量: 程序用来存储数据的一块内存空间,程序在运行过程中可以对其存储的数据进行改变,所以叫做变量 常量:相对于变量来说,其值是不可改变的 整数类型(byte short int long) b ...
- 【转载】 mybatis入门系列四之动态SQL
mybatis 详解(五)------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when, ...
- Docker & ASP.NET Core (1):把代码连接到容器
和这种蛋糕一样,Docker的容器和镜像也是使用类似的分层文件系统构建而成的. 这样做的好处就是可以节省硬盘空间,也利于复用等等.因为Docker基于镜像创建容器的时候,其镜像是共享的:而且镜像里面的 ...
- Spring之旅第五篇-AOP详解
一.什么是AOP? Aspect oritention programming(面向切面编程),AOP是一种思想,高度概括的话是“横向重复,纵向抽取”,如何理解呢?举个例子:访问页面时需要权限认证,如 ...
- LindDotNetCore~ISoftDelete软删除接口
回到目录 概念 ISoftDelete即软删除,数据在进行delete后不会从数据库清除,而只是标记一个状态,在业务范围里都不能获取到这个数据,这在ORM框架里还是比较容易实现的,对传统的ado来说需 ...
- 滤波器——BoxBlur均值滤波及其快速实现
个人博客地址:滤波器--BoxBlur均值滤波及其快速实现 动机:卷积核.滤波器.卷积.相关 在数字图像处理的语境里,图像一般是二维或三维的矩阵,卷积核(kernel)和滤波器(filter)通常指代 ...
- 在Xunit中使用FsCheck
目录 编写基于Property-based的单元测试 使用FsCheck编写Property-based测试 在Xunit中使用FsCheck 使用FsCheck编写Model-based测试-待续 ...
- ios键盘弹起 body的高度拉长,页面底部空白问题。ios软键盘将页面抵到上面后,关闭软键盘页面不回弹的问题。
js 监听ios手机键盘弹起和收起的事件 /* js 监听ios手机键盘弹起和收起的事件 */ document.body.addEventListener('focusin', () => { ...
- DevOps实例
DevOps实例 ------------------------------------------------------------------ 今天先到这儿,希望对您DevOPS, 技术领导力 ...
- 物联网RFID技术之应用ETC系统
背景 信息物理系统CPS通过集成先进的感知.计算.通 信.控制等信息技术和自动控制技术,构建了物理空间与信息空间中人. 机.物.环境.信息等要素相互映射.适时交互.高效协同的复杂系统, 实现系统内资源 ...