一道贪心+类背包DP的好题

首先发现一个十分显然的性质,没有这个性质整道题目都难以下手:

无论两队的顺序如何,总是让吃饭慢的人先排队

这是一个很显然的贪心,因为如果让吃饭慢的排在后面要更多的时间至少没有这样优

因此我们先按吃饭时间从大到小sort一下

然后我们发现这是一个类01背包的DP,只不过这里的状态要么是01,要么是10(即要么在1队,要么在2队)

然后这种东西都有一些很神奇的性质,比如说我们用前缀和sum[i]表示前i个人中排队的总时间,那么

sum[i]-前i个人中去1号窗口的人的打饭时间之和=前i个人中去1号窗口的人的打饭时间之和

然后我们可以想出一个DP,用f[i][j]表示前i个人中,在1号窗口排队的人共花了j分钟排队的最优情况下,最少要多少时间(要和2号窗口的取一个min),包括吃饭的时间

然后就有转移:

  • f[i][j]=min(f[i][j],max(f[i-1][j-a[i].t],j+a[i].e))(在1号窗口打饭)

  • f[i][j]=min(f[i][j],max(f[i-1][j],sum[i]-j+a[i].e)(在2号窗口打饭)

然后我们发现这个可以滚动存储不过也没这个必要,但是我还是写了

CODE

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=205;
struct data
{int t,e;
}a[N];
int n,f[2][N*N],sum[N],ans;
inline char tc(void)
{static char fl[100000],*A=fl,*B=fl;return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{x=0; char ch=tc();while (ch<'0'||ch>'9') ch=tc();while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline bool comp(data a,data b)
{return a.e>b.e;
}
inline int min(int a,int b)
{return a<b?a:b;
}
inline int max(int a,int b)
{return a>b?a:b;
}
int main()
{//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);register int i,j;for (read(n),i=1;i<=n;++i)read(a[i].t),read(a[i].e);sort(a+1,a+n+1,comp);for (i=1;i<=n;++i)sum[i]=sum[i-1]+a[i].t;memset(f[0],63,sizeof(f[0])); f[0][0]=0;for (i=1;i<=n;++i){int now=i&1,last=now^1;memset(f[now],63,sizeof(f[now])); ans=f[now][0];for (j=sum[i];j>=0;--j){if (j>=a[i].t) f[now][j]=min(f[now][j],max(f[last][j-a[i].t],j+a[i].e));if (sum[i]-j>=a[i].t) f[now][j]=min(f[now][j],max(f[last][j],sum[i]-j+a[i].e));}}for (i=0;i<=sum[n];++i)ans=min(ans,f[n&1][i]);printf("%d",ans);
}

转载于:https://www.cnblogs.com/cjjsb/p/9016515.html

Luogu P2577 [ZJOI2005]午餐相关推荐

  1. P2577 [ZJOI2005]午餐

    题面:https://www.luogu.org/problem/P2577 本题一旦设出f[i][j]表示前i个人,在1号窗口打饭总时间j,最早吃完饭的时间 那么就很容易想到 当把i放在1号窗口 f ...

  2. ZJOI2005午餐

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

  3. [ZJOI2005]午餐(贪心+dp)

    首先若只有一个窗口,利用贪心,按吃饭时间从大到小排序即可 正确性证明: 定义 eat[i] = 第i个人的吃饭时间,time[i] = 第i个人的打饭时间 延长时间T[i]=max(eat[i]- ∑ ...

  4. [ZJOI2005]午餐

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

  5. [ZJOI2005]午餐 贪心+dp

    这个题如果直接dp的话要考虑 先从题目类型入手,这种规划性问题 应该是个dp 1开始的时间.1结束的时间.2开始的时间.2结束的时间 这是200^6级别的状态数,且没有任何状态优化的余地 所以就要考虑 ...

  6. 2018.12-2019.1 TO-DO LIST

    AC自动机 P3808 [模板]AC自动机(简单版)(完成时间:2018.12.06) P3796 [模板]AC自动机(加强版)(完成时间:2018.12.06) P2444 [POI2000]病毒( ...

  7. 洛谷试炼场 动态规划TG.lv(2)

    P1273 有线电视网 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. ...

  8. 【做题记录】DP 杂题

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

  9. 2018年10月训练记录(10.1~10.23)

    前言 这篇博客记录的是我在201820182018年101010月的刷题列表. 由于时间比较匆忙,可能会有一些空链接,但我会尽快将它们补齐的. (目前链接已补至Oct7thOct\ 7thOct 7t ...

最新文章

  1. java 防止文件下载_Spring,Java:流式文件下载以避免内存不足错误
  2. 解决 C/C++ 程序执行后控制台一闪而过的方法
  3. ifconfig详解及设置静态IP的方法
  4. A Full Hardware Guide to Deep Learning
  5. android 扫描重复文件,Android Gradle在APK META-INF中复制的重复文件
  6. 《DirectX 9.0 3D游戏开发编程基础》 第一章 初始化Direct3D 读书笔记
  7. Android系统(45)--Monkey 测试相关知识
  8. 63.1拓展之box-shadow属性
  9. IC卡读写器开发说明
  10. 用计算机制作模拟汽车,计算机模拟在汽车行业应用将兴起
  11. FlashFXP 在win10下不能拖放操作的解决方法
  12. 你一定要狠狠的幸福,那个凶丫头(2)
  13. 基于单片机的超声波测距仪的设计
  14. macpro如何清理磁盘空间_如何在Mac上清除磁盘空间(2020年最佳技巧)
  15. 最好用的 6 款 Vue 实时消息提示通知(Message/Notification)组件推荐与测评
  16. 迷你世界迷你编程 v1.0
  17. CentOS8中如何支持TL-WDN7200H无线USB网卡?
  18. 【案例分享】建筑材料智能化生产工厂一一智能制造平台搭建
  19. C++ —— 类的使用
  20. opa example

热门文章

  1. android 铃声位置
  2. CSDN移动博文集锦之Android核心分析 (Z)
  3. 深入浅出深度学习(三)线性代数基础
  4. mlflow_使用MLflow跟踪进行超参数调整
  5. AR模型与数据平稳性之间的关系
  6. 把王小波作为离我们最近的一个大师
  7. 低级键盘钩子 DLL
  8. 域服务器怎么修改管理员密码,域服务器更改客户端管理员的密码
  9. python如何使用多态_在python 3中,如何将多态应用于类
  10. python正负数转换,如何在Python中将负整数值转换为十六进制