题目传送门

嗯……我承认我看了题解,不过好歹有了点自己的思路,大约蒙出来了\(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. puppet批量管理500多台服务器

    前言 puppet使用了有一段时间了,之前写的手顺书一直未发布到blog上来,今天正好有空,写下一点笔记.公司在用的服务器有500多台,基本都为CentOS,版本有5和6两种,管理起来很不方便,尤其是 ...

  2. linux下oracle一些常用命令

    dbca 配置数据库netca 配置tnslsnrctl status tns状态lsnrctl stop TNS停止lsnrctl start TNS启动

  3. CF10D/POJ2127 LCIS解题报告

    题目传送门(洛谷)(CF)(POJ) 前言 期末考试前的最后一篇题解,希望期末考  rp++ 奇怪,为什么在CF上能过的代码到POJ上就 听取WA声一片  (不管了) 题目思路 LCIS模版O(n²) ...

  4. spring静态工厂方法得到单例bean

    import org.springframework.beans.BeansException; import org.springframework.context.ApplicationConte ...

  5. 【ACM】取石子 - 博弈论

    取石子(一) 时间限制:3000 ms  |  内存限制:65535 KB 难度:2   描述 一天,TT在寝室闲着无聊,和同寝的人玩起了取石子游戏,而由于条件有限,他/她们是用旺仔小馒头当作石子.游 ...

  6. VALID_FOR in db standby

    检查DG 装填: 目标主机检查mrp是否正常: SELECT PROCESS FROM V$MANAGED_STANDBY WHERE PROCESS LIKE 'MRP%';--若mrp没有启动,则 ...

  7. 文件系统满的话(filesystem full),该如何处理。(du and ls)

    #!/bin/bash function ergodic(){ ` do "/"$file ] then ergodic $"/"$file else loca ...

  8. 【Unity3D】简要分析unity3d中剪不断理还乱的yield

    在学习unity3d的时候很容易看到下面这个例子: void Start () { StartCoroutine(Destroy()); } IEnumerator Destroy(){ yield ...

  9. Second Highest Salary

    Write a SQL query to get the second highest salary from the Employee table. +----+--------+ | Id | S ...

  10. qrcode.js的识别解析二维码图片和生成二维码图片

    qrcode只通过前端就能生成二维码和解析二维码图片, 首先要引入文件qrcode.js,下载地址为:http://static.runoob.com/download/qrcodejs-04f46c ...