[HNOI2001]产品加工

洛谷题面

清新 DP 题。

题目大意

n 个任务,第 i 个任务可以给 A 机器做,用时 t1[i];给 B 机器做,用时 t2[i];给 A 机器和 B 机器同时做,用时 t3[i]

求最小用时。

当对应 t[i]=0 时,代表不能给这个机器或这两个机器做。

题目分析

dp[i][j][k] 表示完成了前 i 个任务,第一台机器耗时为 j,另一台耗时为 k,此时的最小总用时。

最终答案即为 min{dp[n][j][k]}

先不论时间,即便用上滚动数组优化,空间复杂度也已经炸成花了,我们考虑一个巧妙的优化:

dp[i][j] 表示完成了前 i 个 任务,第一台机器耗时为 j 时第二台机器的最小耗时。

直接将 【第二台机器耗时】 这个东西干掉了!(

本题中状态转移方程并非重点,但还是摆上来:

dp[i][j]=min{dp[i1][j]+t2[i],dp[i1][jt1[i]],dp[i1][jt3[i]]+t3[i]}

仍然是可以滚动优化的。

时间复杂度 O(nk),空间复杂度 O(ns)

st1,t2,t3 的取值范围,ki=1nmax{t1[i],t2[i],t3[i]}k 最大为 6×103×5=3×104

可以通过本题。

代码

//2022/1/8

const int INF=0x3f3f3f3f;

const int ma1=6005,ma2=30005;

int t1[ma1],t2[ma1],t3[ma1];

int dp[2][ma2];

int n;

int main(void)
{
	n=read();
	
	mst(dp,0x3f);
	
	dp[0][0]=0;
	
	for(register int i=1;i<=n;i++)
	{
		t1[i]=read(),t2[i]=read(),t3[i]=read();
	}
	
	int sum(0);
	
	for(register int i=1;i<=n;i++)
	{
		mst(dp[i&1],0x3f);
		 
		sum+=max({t1[i],t2[i],t3[i]});
		
		for(register int j=0;j<=sum;j++)
		{	
			if(t2[i]!=0) 
			{
				dp[i&1][j]=min(dp[i&1][j],dp[i&1^1][j]+t2[i]);
			}
			
			if(t1[i]!=0 && j>=t1[i]) 
			{
				dp[i&1][j]=min(dp[i&1][j],dp[i&1^1][j-t1[i]]);
			}
			
			if(t3[i]!=0 && j>=t3[i]) 
			{
				dp[i&1][j]=min(dp[i&1][j],dp[i&1^1][j-t3[i]]+t3[i]);
			}
		}
	}
	
	int ans=INF;
	
	for(register int i=0;i<=sum;i++)
	{
		ans=min(ans,max(i,dp[n&1][i]));
	}
	
	printf("%d\n",ans);
	
	return 0;
}

本文作者:Coros_Trusds

本文链接:https://www.cnblogs.com/Coros-Trusds/p/15778672.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Coros_Trusds  阅读(33)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.