首先可以数学地证明:可对所有人按吃饭时间从大到小排序
然后会想到表示前
个人,一队用
时间打饭,另一队用
时间打饭的最小用时。
思想就是知道,就可以保证没有后效性。
但数组开不下,这时发现,便可以去掉以为一维。
还有要注意的就是初始化的问题了。
#include<algorithm> #include<iostream> #include<cstdio> int read(); #define inf 2000000000 #define rep(i,a,b) for(int i=(a);i<=(b);i++) using namespace std; const int maxn=220; int maxx(int a,int b){return a<b?b:a;} int miin(int a,int b){return a>b?b:a;} struct Ren{ int a,t; bool operator < (const Ren &b)const{ return t>b.t; } }ren[maxn]; int n,s[maxn],f[maxn][maxn*maxn]; int main(){ cin>>n; rep(i,1,n)cin>>ren[i].a>>ren[i].t; sort(ren+1,ren+n+1); s[0]=0; rep(i,1,n)s[i]=s[i-1]+ren[i].a; rep(i,0,n) rep(a,0,(i==n)?(s[i]):(s[i+1])) f[i][a]=inf; f[0][0]=0; rep(i,1,n) rep(a,0,s[i]){ f[i][a]=miin(f[i][a],maxx(f[i-1][a],s[i]-a+ren[i].t)); if(a>=ren[i].a) f[i][a]=miin(f[i][a],maxx(f[i-1][a-ren[i].a],a+ren[i].t)); } int Ans=inf; rep(a,0,s[n])Ans=miin(Ans,f[n][a]); cout<<Ans; } int read(){ int s=0,k=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')k=-1;ch=getchar();} while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();} return s*k; }