题目:https://www.luogu.org/problemnew/show/P2577
首先,想一想可以发现贪心策略是把吃饭时间长的人放在前面;
设 f[i][j] 表示考虑到第 i 个人,目前第一个窗口排队总时间 j ,所有人吃完最晚的时刻;
于是可以算出来第二个窗口的排队总时间,就可以转移了;
把第 i 个人放在第一个窗口或第二个窗口,转移顺序竟然会影响答案??!!!总之把第一个窗口放在前面居然就错了!
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int const maxn=205,inf=0x3f3f3f3f; int n,f[3][40005],ans;//maxn*maxn!! struct N{int t,e;}a[maxn]; bool cmp(N x,N y){return x.e>y.e;} int main() { scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&a[i].t,&a[i].e); sort(a+1,a+n+1,cmp); memset(f,0x3f,sizeof f); // memset(f[0],0,sizeof f[0]); f[0][0]=0;//! int lm=a[1].t,d=1; for(int i=1;i<=n;i++,lm+=a[i].t,d=!d) for(int j=0;j<=lm;j++) { // if(j>=a[i].t) // f[d][j]=max(f[!d][j-a[i].t],j+a[i].e); // if(f[!d][j])f[d][j]=min(f[d][j],max(f[!d][j],lm-j+a[i].e));//顺序?! if(f[!d][j])f[d][j]=max(f[!d][j],lm-j+a[i].e);//if(f[!d][j])! if(j>=a[i].t) f[d][j]=min(f[d][j],max(f[!d][j-a[i].t],j+a[i].e)); } d=!d; ans=inf; for(int j=0;j<=lm;j++)ans=min(ans,f[d][j]); printf("%d ",ans); return 0; }