博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ZJOI2004 午餐
阅读量:5032 次
发布时间:2019-06-12

本文共 1882 字,大约阅读时间需要 6 分钟。

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

转载于:https://www.cnblogs.com/wxl-Ezio/p/10159014.html

你可能感兴趣的文章
[CF508E] Arthur and Brackets
查看>>
[CF1029E] Tree with Small Distances
查看>>
tp5.0中及其常用方法的一些函数方法(自己看)和技巧(不断添加中)
查看>>
美团推荐算法实践
查看>>
Netty官方示例
查看>>
[数分提高]2014-2015-2第4教学周第2次课
查看>>
ansible进阶小技巧--tags
查看>>
JSP页面跳转方式
查看>>
发布高性能迷你React框架anu
查看>>
Python中Gradient Boosting Machine(GBM)调参方法详解
查看>>
利用DDE通信将PLC数据传输到EXCEL
查看>>
Eclipse 实用快捷键大全
查看>>
与非门和或门实现异或门
查看>>
golang统计出其中英文字母、空格、数字和其它字符的个数
查看>>
poj 1782 Run Length Encoding
查看>>
《自我介绍》
查看>>
在线考试系统设计思路
查看>>
p1150[noip2013普及]表达式求值
查看>>
POST和GET有什么区别?
查看>>
js基础
查看>>