题解:
有一个贪心策略:吃饭时间越长的越早打饭
然后动规,f[i][j]表示前i-1个数,第一个队列恰好要j的时间的最晚集合时间
可以降维,把i去掉
初始化:f[0]=0,其余为正无穷
第一个窗口打饭:
f[j]=min(f[j],max(f[j-x],j+y)) (x<=j<=sum)
=>f[j+x]=min(f[j+x],max(f[j],j+x+y)) (0<=j<=sum-x)
第二个窗口打饭:
f[j]=max(f[j],sum-j+y)
ans=max(f[i])
注意,这里的sum指a[1].x+a[2].x+…+a[i].x,而标程中的sum是少一个a[i].x的,所以题解和标程的状态转移方程不同
标程:
#include<bits/stdc++.h>
using namespace std;
struct kk{
int x,y;
}a[203];
int n,i,j,x,y,f[40003],ans,sum;
int cmp(kk x,kk y){
return x.y>y.y;
}
int main(){
cin>>n;
for (i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);
memset(f,1,sizeof(f));
ans=f[0];f[0]=0;
for (i=1;i<=n;i++){
x=a[i].x;y=a[i].y;
for (j=sum;j>=0;j--){
f[j+x]=min(f[j+x],max(f[j],j+x+y));
f[j]=max(f[j],sum-j+x+y);
}
sum+=x;
}
for (i=1;i<=sum;i++) ans=min(ans,f[i]);
cout<<ans;
}