题目传送门

嗯……我承认我看了题解,不过好歹有了点自己的思路,大约蒙出来了\(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. OnclickListener

    https://developer.android.com/reference/android/view/View.OnClickListener.html# https://blog.csdn.ne ...

  2. 小程序组件交互 -- 传入js

    1.父组件(wxml页面)向子组件传递 在子组件中定义需要传入的属性 properties: { count: { type: Number, value: 0, observer:function( ...

  3. Django基础(1)

    昨日内容回顾: 1. socket创建服务器 2. http协议: 请求协议 请求首行 请求方式 url?a=1&b=2 协议 请求头 key:value 请求体 a=1&b=2(只有 ...

  4. Java排序算法(二)

    java排序算法(二) 二.改进排序算法 2.1希尔排序 定义:希尔排序(ShellSort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本.希尔排序是非稳定排序算法. ...

  5. Java开发笔记(九十八)利用Callable启动线程

    前面介绍了如何利用Runnable接口构建线程任务,该方式确实方便了线程代码的复用与共享,然而Runnable不像公共方法那样有返回值,也就无法将线程代码的处理结果传给外部,造成外部既不知晓该线程是否 ...

  6. vue地址插件多级联动自适应 + github地址

    https://github.com/cqzyl/vue-manyAddress

  7. cron 任务执行表达式

    1.来源 开始我还不知道cron到底来源于哪里,不求甚解的我也没做过多了解,现在突然用到所以写一下. cron计划任务  其实只是linux 一个执行计划的一个工具或者执行程序. 在Linux系统中, ...

  8. 构建第一个Spring Boot2.0应用之Controller(三)

    Controller控制器主要是接收浏览器请求.下面说一说@Controller注解和@RestController的区别: (1)@Controller类中的方法可以直接通过返回String跳转到j ...

  9. CAS登录认证的简单介绍

    参考博客:  https://www.jianshu.com/p/8daeb20abb84 下面是CAS最基本的协议过程: 下面是CAS Web工作流程图: 名词解释 Ticket Grangting ...

  10. iOS核心动画高级技巧之CALayer(一)

    iOS核心动画高级技巧之CALayer(一) iOS核心动画高级技巧之图层变换和专用图层(二)iOS核心动画高级技巧之核心动画(三)iOS核心动画高级技巧之性能(四)iOS核心动画高级技巧之动画总结( ...