1. 程式人生 > >luogu2577/bzoj1899 午餐 (貪心+dp)

luogu2577/bzoj1899 午餐 (貪心+dp)

div pac stdin pri def for str clu n)

首先,應該盡量讓吃飯慢的排在前面,先按這個排個序

然後再來決定每個人到底去哪邊

設f[i][j]是做到了第i個人,然後1號窗口目前的總排隊時間是j,目前的最大總時間

有這個i和j的話,再預處理出前i個人的排隊總時間sum[i],可以知道在2號窗口的排隊時間是sum[i]-j

拿著兩個去更新答案就行了

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long
long ll; 6 const int maxn=210; 7 8 inline ll rd(){ 9 ll x=0;char c=getchar();int neg=1; 10 while(c<0||c>9){if(c==-) neg=-1;c=getchar();} 11 while(c>=0&&c<=9) x=x*10+c-0,c=getchar(); 12 return x*neg; 13 } 14 15 int f[maxn][maxn*maxn],st[maxn];
16 int N; 17 struct Node{ 18 int e,q; 19 }p[maxn]; 20 21 inline bool cmp(Node a,Node b){return a.e>b.e;} 22 23 int main(){ 24 //freopen("","r",stdin); 25 int i,j,k; 26 N=rd(); 27 for(i=1;i<=N;i++){ 28 p[i].q=rd(),p[i].e=rd(); 29 }sort(p+1,p+N+1,cmp);
30 for(i=1;i<=N;i++) 31 st[i]=st[i-1]+p[i].q; 32 33 CLR(f,127);f[0][0]=0; 34 for(i=1;i<=N;i++){ 35 for(j=0;j<=N*200;j++){ 36 if(f[i-1][j]>=1e8) continue; 37 f[i][j+p[i].q]=min(f[i][j+p[i].q],max(f[i-1][j],j+p[i].q+p[i].e)); 38 f[i][j]=min(f[i][j],max(f[i-1][j],st[i]-j+p[i].e)); 39 } 40 } 41 int ans=1e9; 42 for(j=0;j<=N*200;j++) 43 ans=min(ans,f[N][j]); 44 printf("%d\n",ans); 45 return 0; 46 }

luogu2577/bzoj1899 午餐 (貪心+dp)