luogu2577/bzoj1899 午餐 (贪心+dp)

首先,应该尽量让吃饭慢的排在前面,先按这个排个序

然后再来决定每个人到底去哪边

设f[i][j]是做到了第i个人,然后1号窗口目前的总排队时间是j,目前的最大总时间

有这个i和j的话,再预处理出前i个人的排队总时间sum[i],可以知道在2号窗口的排队时间是sum[i]-j

拿着两个去更新答案就行了

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int f[maxn][maxn*maxn],st[maxn];
int N;
struct Node{
int e,q;
}p[maxn]; inline bool cmp(Node a,Node b){return a.e>b.e;} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd();
for(i=;i<=N;i++){
p[i].q=rd(),p[i].e=rd();
}sort(p+,p+N+,cmp);
for(i=;i<=N;i++)
st[i]=st[i-]+p[i].q; CLR(f,);f[][]=;
for(i=;i<=N;i++){
for(j=;j<=N*;j++){
if(f[i-][j]>=1e8) continue;
f[i][j+p[i].q]=min(f[i][j+p[i].q],max(f[i-][j],j+p[i].q+p[i].e));
f[i][j]=min(f[i][j],max(f[i-][j],st[i]-j+p[i].e));
}
}
int ans=1e9;
for(j=;j<=N*;j++)
ans=min(ans,f[N][j]);
printf("%d\n",ans);
return ;
}
上一篇:Quartz.Net进阶之一:初识Job作业和触发器


下一篇:如何用ftp上传静态网站到虚拟空间