洛谷P2224产品加工

[HNOI2001] 产品加工

题目描述

某加工厂有 A、B 两台机器,来加工的产品可以由其中任何一台机器完成,或者两台机器共同完成。由于受到机器性能和产品特性的限制,不同的机器加工同一产品所需的时间会不同,若同时由两台机器共同进行加工,所完成任务又会不同。

某一天,加工厂接到 n 个产品加工的任务,每个任务的工作量不尽一样。

你的任务就是:已知每个任务在 A 机器上加工所需的时间 t1,B 机器上加工所需的时间 t2 及由两台机器共同加工所需的时间 t3,请你合理安排任务的调度顺序,使完成所有 n 个任务的总时间最少。

输入格式

第一行为一个整数 n

接下来 n 行,每行三个非负整数 t1,t2,t3,分别表示第 i 个任务在 A 机器上加工、B 机器上加工、两台机器共同加工所需要的时间。如果所给的时间 t1t20 表示任务不能在该台机器上加工,如果 t30 表示任务不能同时由两台机器加工。

输出格式

仅一行一个整数,表示完成所有 n 个任务的最少总时间。

关于本题:

也是头一次见这种状态定义方式比较特殊的,我们发现对于任务排序不太好做,考虑dp,那么状态的设计呢

Sol:

(1).f[i][t1][t2]:表示前i个任务,A用时t1,B用时t2是否可行
我们发现maxt大约在6000*5=30000,空间时间都不允许,考虑降维

(2).f[i][t1]:表示前i个任务,A用时t1,B的最小用时,这一步是把B的状态取消固定
但是此时发现空间为 6000*30000=180000000=1.8 * 10^8,MLE

(3).转移时发现f[i]之和f[i-1]有关,滚动一下就行了

滚动后记得数组赋初始值,然后你就要用memset每次对f[last]这一行赋值了对吗?你会TLE得理所应当。
原因是多次调用memset使程序效率降低,那我们干脆就用临时变量算了,由于再滚动了一维,所以maxt要倒序枚举

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
const int N=3e5+7;
int n,ans=0x3f3f3f3f,s;
int x,y,z,maxt;
int f[N];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>x>>y>>z;
		maxt+=max(max(x,y),z);
		for(int j=maxt;j>=0;j--){
			int tmp=0x3f3f3f3f;
			if(x&&j>=x) tmp=min(tmp,f[j-x]);
			if(y) tmp=min(tmp,f[j]+y);
			if(z&&j>=z) tmp=min(tmp,f[j-z]+z);
			f[j]=tmp;
		}
	}
	for(int i=0;i<=maxt;++i)
		ans=min(ans,max(i,f[i]));
	cout<<ans<<'\n';
	return 0;
}


样例 #1

样例输入 #1

5                            
2 1 0
0 5 0
2 4 1
0 0 3
2 1 1

样例输出 #1

9

提示

对于所有数据,有 1n6×1030t1,t2,t35

posted @   爱艺诗篇  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示