题目简述

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时最少话费的总时间

得出状态转移方程

  1. for(re int i=;i<=n;++i)//i表示当前第i个人
  2. {
  3. for(re int j=;j<=sum[i];++j)//j表示当前花费的等待时间
  4. {
  5. if(j>=stu[i].a)
  6. 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)转移而来
  7. //DP[i-1][j-stu[i].a]表示除去第i个人的总时间,因为有可能前面i-1个人还没吃饭第i个人就吃完了(队伍最后离开的是前i-1个人)
    //j+stu[i]表示第i个人排队吃饭的时间(队伍最后离开的是第i个人)
  8. 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个人的等待时间总和
  9. }
  10. }

code

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<cstring>
  6. #define maxn 205
  7. #define maxt 40010
  8. #define re register
  9. using namespace std;
  10. int DP[maxn][maxt],sum[maxn],n;
  11. struct POP{
  12. int a,b;
  13. }stu[maxn];
  14. inline int read()
  15. {
  16. int x=,f=; char ch=getchar();
  17. while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
  18. while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
  19. return x*f;
  20. }
  21. bool cmp(POP A,POP B)
  22. {
  23. return A.b>B.b;
  24. }
  25. int main()
  26. {
  27. n=read();
  28. for(re int i=;i<=n;++i)
  29. {
  30. stu[i].a=read();
  31. stu[i].b=read();
  32.  
  33. }
  34. memset(DP,,sizeof(DP));
  35. sort(stu+,stu+n+,cmp);
  36. for(re int i=;i<=n;++i)
  37. {
  38. sum[i]=sum[i-]+stu[i].a;
  39. }jiufftts
  40. DP[][]=;
  41. for(re int i=;i<=n;++i)
  42. {
  43. for(re int j=;j<=sum[i];++j)
  44. {
  45. if(j>=stu[i].a)
  46. DP[i][j]=min(DP[i][j],max(DP[i-][j-stu[i].a],j+stu[i].b));
  47.  
  48. DP[i][j]=min(DP[i][j],max(DP[i-][j],sum[i]-j+stu[i].b));
  49. }
  50. }
  51. int ans=;
  52. for(re int i=;i<=sum[n];++i)
  53. ans=min(ans,DP[n][i]);
  54. printf("%d",ans);
  55. return ;
  56. }

【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. IM开发者的零基础通信技术入门(一):通信交换技术的百年发展史(上)

    [来源申明]本文原文来自:微信公众号“鲜枣课堂”,官方网站:xzclass.com,原题为:<通信交换的百年沧桑(上)>,本文引用时已征得原作者同意.为了更好的内容呈现,即时通讯网在收录时 ...

  2. 使用 JWT 生成 Token 代码示例

    JSON Web Token,简称 JWT, 是一个开放的标准(RFC 7519),它定义了以一种紧凑的.自包含的 JSON 对象在各方之间安全传输信息的方式.该信息含有数字签名,可以被验证和信任. ...

  3. lua-nginx-module模块里ngx_lua的所有指令以及可用ngx所有方法

    http://www.04007.cn/article/430.html

  4. asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程

    最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...

  5. vimium使用

    vimium使用 chrome下面的vimium插件已经慕名已久,迟迟没有做尝试,今天在家有空就熟悉了一下vimium,感觉还是棒棒的.记录一下一些使用心得. 常用按钮 j 向上滚动 k 向下滚动 d ...

  6. springBoot(13)---整合Druid实现多数据源和可视化监控

    SpringBoot整合Druid实现多数据源和可视化监控 先献上github代码地址:https://github.com/yudiandemingzi/springboot-manydatasou ...

  7. qml demo分析(maskedmousearea-异形窗口)

    一.效果展示 如本文的标题所示,这篇文章分析的demo是一个异形窗口,主要展示鼠标在和异形区域交互的使用,效果如图1所示,当鼠标移动到白云或者月亮上时,相应的物体会高亮,当鼠标按下时,物体会有一个放大 ...

  8. Android屏幕适配和方案【整理】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这里只是根据参考资料整理下,具体内容请阅读参考资料. 原型设计图 推荐1倍效果图,即采用 720 * 360 大小( 1280 *7 ...

  9. TabLayoutViewPagerDemo【TabLayout+ViewPager可滑动】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用TabLayout搭配ViewPager实现可滑动的顶部选项卡效果. 效果图 代码分析 1.演示常规的设置. 2.通过自定义Vi ...

  10. unity协程coroutine浅析

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.序言 在unity的游戏开发中,对于异步操作,有一个避免不了的操作: 协程,以前一直理解的懵懵懂懂,最近认真充电了一下 ...