题目传送门

嗯……我承认我看了题解,不过好歹有了点自己的思路,大约蒙出来了\(30\%\)(个人感觉)……

学会\(DP\),任重而道远啊!


Step1.贪心排序

先将每个人按吃饭的快慢排序,然后再进行\(DP\)
稍微证明一下这个贪心吧

证明

设两个人排队和吃饭的时间分别为\(a_1,b_1\)和\(a_2,b_2\), 且\(b_1 > b_2\),那么\(1\)同学在前时,所花费的总时间为\((a_1+b_1)+(a_2+b_2-b_1)\)(因为\(1\)同学吃饭的时间和\(2\)同学打饭并吃饭的时间是重叠的,所以要减去)
化简后为\(a_1+a_2+b_2\)
同理,如果\(2\)同学在前,总时间为\(a_1+a_2+b_1\)
因为\(b_1 > b_2\),所以\(1\)同学在前时花费的总时间少

当然,如果\(b_1 \geq a_2+b_2\)时,\((a_1+b_1)+(a_2+b_2-b_1)\)化简后应为\(a_1+b_1\)(因为不可能存在负数时间)
但即使这样,\(1\)同学在前仍然更优,因为\(a_1+b_1\)显然\(<a_1+a_2+b_1\)

Step2.DP

状态

f[i][j]表示前\(i\)个人在\(1\)号窗口排队打饭的时间为\(j\)时,吃完饭的时间

转移方程

  • 当第\(i\)个人在\(1\)号窗口打饭时
if(p[i].a<=j) f[i][j]=min(f[i][j],max(f[i-1][j-p[i].a],j+p[i].b));

因为全部吃完饭的时刻为最后一个人吃完饭的时刻,即\(max(\text{i同学打完饭的时间+i同学吃饭的时间})\),而新加进来的这名同学有可能是最后一个吃完的,所以要max(f[i-1][j-p[i].a],j+p[i].b)),即在加这位同学之前的最晚时间和这位同学吃完饭的时间中取一个最大值。

  • 当第\(i\)个人在\(2\)号窗口打饭时
f[i][j]=min(f[i][j],max(f[i-1][j],suma[i]-j+p[i].b));

\(max\)函数同理,suma[i]表示前\(i\)位同学打饭所花的时间

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int k=0; char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9')
      k=k*10+c-48, c=getchar();
    return k;
}
struct zzz{
    int a,b;
}p[210];
bool cmp(zzz x,zzz y){
    return x.b > y.b;
}
int f[210][40010],f2[210],ti[210][210],suma[210];
int main(){
    int n=read();
    for(int i=1;i<=n;i++)
      p[i].a=read(),p[i].b=read();
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=n;i++)
      suma[i]=suma[i-1]+p[i].a;
    memset(f,127,sizeof(f));
    f[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=suma[i];j++){
            if(p[i].a<=j) f[i][j]=min(f[i][j],max(f[i-1][j-p[i].a],j+p[i].b));
            f[i][j]=min(f[i][j],max(f[i-1][j],suma[i]-j+p[i].b));
        }
    }
    int ans=2147483647;
    for(int i=1;i<=suma[n];i++)
      ans=min(ans,f[n][i]);
    cout<<ans;
    return 0;
}

ZJOI2004 午餐的更多相关文章

  1. 2021record

    2021-10-14 P2577 [ZJOI2004]午餐 2021-10-13 CF815C Karen and Supermarket(小小紫题,可笑可笑) P6748 『MdOI R3』Fall ...

  2. 【做题记录】DP 杂题

    P2577 [ZJOI2004]午餐 $\texttt{solution}$ 想到贪心: 吃饭慢的先打饭节约时间, 所以先将人按吃饭时间从大到小排序. 状态: \(f[i][j]\) 表示前 \(i\ ...

  3. 【BZOJ1899】[Zjoi2004]Lunch 午餐 贪心+DP

    [BZOJ1899][Zjoi2004]Lunch 午餐 Description 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时 ...

  4. bzoj 1899: [Zjoi2004]Lunch 午餐

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

  5. 【bzoj1899】[Zjoi2004]Lunch 午餐 dp

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

  6. Bzoj1899: [Zjoi2004]Lunch 午餐

    题面 传送门 Sol 首先显然吃饭久的要排在前面 之后再来分配队伍,设\(f[i][j]\)表示到第\(i\)个人,\(A\)队伍要等\(j\)的最小吃完饭时间 那么就是一个简单的背包吧... # i ...

  7. [BZOJ1899][ZJOI2004]Lunch 午餐 (DP)

    比较水的DP 但是比较难想 整体思路还是很好理解的 在洛谷的题解里有一个一维的 > 什么时候去看一下 下面发我的代码 #include<bits/stdc++.h> #define ...

  8. 【bzoj1899】[Zjoi2004]Lunch 午餐(贪心+dp)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1899 显然为了节省时间,吃饭慢的人要先打饭.于是我们可以先把所有人按吃饭时间排序,于是 ...

  9. BZOJ 1899&&luogu P2577: [Zjoi2004]Lunch 午餐 贪心+DP

    贪它,再大力DP(话说觉得此题简单的真的是大佬QAQ)我想了两天...QWQ 贪心:吃饭慢的先打饭(不太会证...) DP:f[i][j]表示前i个人,在1号窗口打饭的总时间时j,的最短时间 确定i的 ...

随机推荐

  1. jmeter-逻辑控制器之 交替控制器(实现2个请求每次只执行其中一个)

    交替控制器: 案例:两个请求每次只能执行其中一个,可使用交替控制器. 1.线程组->添加->逻辑控制器->交替控制器 2.在控制下添加两个http请求.运行的时候第一次循环执行第一个 ...

  2. python右键Edit with IDLE

    在windows下试用python,Py文件的右键菜单有个Edit with IDLE,虽然这个ide不是那么功能强大,但是胜在方便.对于脚本语言的一般使用来说是足够了.但是有时候,这个菜单就消失了, ...

  3. excel单元格内容拆分

    这几天在整理数据,但是数据都在表格的一个单元格中,看起来很不方法,所以在网上找到excel单元格内如拆分的方法,并亲测有效 介绍2种拆分的方法 方法一: (1)在B1输入公式=right(text,[ ...

  4. 注意sqlite3和java的整数数据类型的区别

    作为新手的我,没有考虑数据库和java的数据类型的对应上的区别: sqlite3的数据类型和java数据类型对应上要小心,特别是整数类型. java 中int类型4位存储,范围 -2^31到2^31- ...

  5. UnityError 切换场景灯光变黑问题解决

    编辑器在当前场景时,它的灯光是已经渲染好了,但重新加载的时候灯光没有进行渲染 解决方法如下: Window>>lighting>>Scene面板>>右下角build ...

  6. 工厂模式 jdbc 面向接口dao 开发 单例

    package com.itheima.utils; import java.io.IOException; import java.io.InputStream; import java.util. ...

  7. launchctl

    Launchctl 系统启动时, 系统会以root用户的身份扫描/System/Library/LaunchDaemons和/Library/LaunchDaemons目录, 如果文件中有Disabl ...

  8. Docker | 第三章:Docker常用命令

    前言 上一章节,简单介绍了在CentOS下的Docker的安装过程,以及运行了一个官方提供的Hello,World镜像运行了第一个Docker.就像上一章中,验证Docker是否安装成功,我们执行的是 ...

  9. 如何 求Ifeature 的面积

    IArea pArea = pfteature_Source.Shape as IArea;//  IArea来自geometry double dArea = Math.Round(pArea.Ar ...

  10. 解决mac下安装yeoman时没有权限问题

    在mac下安装yeoman经常会出现如下图错误: 解决办法:在命令行执行-- sudo chown -R $USER /usr/local/lib/node_modules 回车就OK