题目简述

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】 午餐的更多相关文章

  1. 洛谷P2577 午餐【贪心】【线性dp】

    题目:https://www.luogu.org/problemnew/show/P2577 题意:n个人每个人有一个打饭时间和吃饭时间,将他们分成两个队伍.每个人打到饭之后就马上去吃饭.问怎么安排可 ...

  2. 洛谷 [P2577] 午餐

    DP + 贪心 我们发现,如果只有一个窗口,贪心即可解决,吃饭时间长的人一定要先打饭 有两个窗口的时候,这条性质依然满足,但是两个窗口如何分配,需要 01 背包 #include <iostre ...

  3. 洛谷P2577 午餐

    题目链接 题意概述:有n个人,第i个人打饭消耗ai时间,离开后吃饭耗费bi时间,将n个人分成两队,合理分配人员使总时间最短并输出总时间. 我们把问题拆分为两个部分.首先是排列顺序,然后是怎么分到两个队 ...

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

    P2577 [ZJOI2005]午餐 )逼着自己做DP 题意: 有n个人打饭,每个人都有打饭时间和吃饭时间.有两个打饭窗口,问如何安排可以使得总用时最少. 思路: 1)可以发现吃饭时间最长的要先打饭. ...

  5. Luogu P2577 [ZJOI2005]午餐(dp)

    P2577 [ZJOI2005]午餐 题面 题目描述 上午的训练结束了, \(THU \ ACM\) 小组集体去吃午餐,他们一行 \(N\) 人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时 ...

  6. P2577 [ZJOI2005]午餐 状压DP

    题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...

  7. P2577 [ZJOI2005]午餐

    题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...

  8. 【题解】洛谷P2577 [ZJOI2005] 午餐(DP+贪心)

    次元传送门:洛谷P2577 思路 首先贪心是必须的 我们能感性地理解出吃饭慢的必须先吃饭(结合一下生活) 因此我们可以先按吃饭时间从大到小排序 然后就能自然地想到用f[i][j][k]表示前i个人在第 ...

  9. [洛谷P2577] [ZJOI2005]午餐

    洛谷题目链接:[ZJOI2005]午餐 题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的 ...

  10. 【洛谷P2577】[ZJOI2005]午餐

    午餐 题目链接 DP题都辣么毒瘤的么.. 首先,看一下题解 我们就有了思路: 贪心:显然,让吃饭慢的先打饭,sort一遍(证明?不存在的.. DP:f[i][j][k]表示前i个人,窗口1的打饭时间为 ...

随机推荐

  1. Sitecore® 8.2 Professional Developer考试心得

    因工作原因入了Sitecore的坑.. 不了解Sitecore认证考试的同学请移步: http://www.cnblogs.com/edisonchou/archive/2018/08/17/9488 ...

  2. Linux系统监控命令详解

    1. top命令 top命令经常用来监控Linux的系统状况,比如cpu.内存的使用,程序员基本都知道这个命令,但比较奇怪的是能用好它的人却很少,例如top监控视图中内存数值的含义就有不少的曲解. 输 ...

  3. 5个常常被大家忽略的Python小技巧

    下面我挑选出的这几个技巧常常会被人们忽略,但它们在日常编程中能真正的给我们带来不少帮助. 1. 字典推导(Dictionary comprehensions)和集合推导(Set comprehensi ...

  4. 听说你的MES系统又失败了?

    前些日子,一位前同事跟我抱怨,他们做的MES系统,凉凉了.这样的话,我从不同人口中听到过不止一次. 我们做的系统,做到一半做不下去了...... 我们的系统,工人都不爱用...... 不只是MES,所 ...

  5. 借助Chrome和插件爬取数据

    工具 Chrome浏览器 TamperMonkey ReRes Chrome浏览器 chrome浏览器是目前最受欢迎的浏览器,没有之一,它兼容大部分的w3c标准和ecma标准,对于前端工程师在开发过程 ...

  6. dubbo-springboot入门级demo

    1. dubbo-springboot入门级demo 1.1. 前言 最后一个做运维的朋友和我提起,他们公司想做个dubbo灰度发布的功能,而这个功能落到了他头上.在我的印象里,dubbo应该可以通过 ...

  7. 【TCP协议】(1)---TCP协议详解

    TCP协议 本文内容如下:      1)TCP协议概念      2)TCP头部结构和字段介绍      3)TCP流量控制            滑动窗口      4)TCP拥塞控制      ...

  8. Elasticsearch Java高级客户端

    1.  概述 Java REST Client 有两种风格: Java Low Level REST Client :用于Elasticsearch的官方低级客户端.它允许通过http与Elastic ...

  9. Kubernetes的污点和容忍(上篇)

    背景 搭建了一个k8s(Kubernetes)的事件监听服务,监听事件之后对数据做处理.有天报了一个问题经调查是新版本的k8s集群添加会把unschedule等信息通过污点的方式反映.而这些污点是只有 ...

  10. java~springboot~ibatis数组in查询的实现

    在ibatis的xml文件里,我们去写sql语句,对应mapper类的方法,这些sql语句与控制台上没什么两样,但在有些功能上需要注意,如where in这种从数组里查询符合条件的集合里,需要在xml ...