[洛谷P2224][题解][HNOI2001]产品加工

题目戳我
看到这个题第一眼:哇塞状态好多怎么维护鸭
第二眼:咦,我们可以用(f[i][j])代表加工到第(i)个产品、第一个机器用了(j)时间时第二个机器用的时间
这样就可以维护所有状态辣~!
解决了我是谁的问题,接下来该考虑我从哪里来
转移可以考虑三种情况:
1.选(t1,f[i][j]=min{f[i-1][j],f[i-1][j-t1]},t1 eq 0&&t1leq j)
2.选(t2,f[i][j]+=t2,t2 eq 0)
3.选(t3,f[i][j]=min{f[i-1][j],f[i-1][j-t3]+t3},t3 eq 0&&t3leq j)
最后统计答案的时候枚举第一个机器的时间,则(ans=min{max{i,f[n][i]}},iin [0,sum max{t1,t2,t3}])
枚举的上界定为(sum max{t1,t2,t3})而不是(min)是因为防止毒瘤出题人令(t3>t1,t2)
这时,你又回去看了这个题第三眼,发现了问题:
数据范围太大啦!!!
没事滚滚就好了把第一维滚掉,Accepted!
Main Code:

#define N 6010
int n,f[N*5],ans=INF,maxt;
int main(){
	Read(n);
	memset(f,0x3f,sizeof(f));
	f[0]=0;
	for(rg int i=1;i<=n;i++){
		int t1,t2,t3;
		Read(t1),Read(t2),Read(t3);
		maxt+=max(max(t1,t2),t3);
		for(rg int j=maxt;j>=0;j--){
			if(t2)f[j]+=t2;
			else f[j]=INF;
			if(t1&&j>=t1)f[j]=min(f[j],f[j-t1]);
			if(t3&&j>=t3)f[j]=min(f[j],f[j-t3]+t3);
		}
	}
	for(rg int i=0;i<=maxt;i++){
		ans=min(ans,max(i,f[i]));
	}
	cout<<ans<<endl;
	return 0;
}

完结撒fa♂