当前位置: 首页 > article >正文

P2224 [HNOI2001]产品加工(进程DP)

P2224 [HNOI2001]产品加工(进程DP)

  • 一、问题
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
  • 二、分析
    • 1、状态表示
    • 2、状态转移
      • 3、空间优化
  • 三、代码

一、问题

题目描述

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

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

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

输入格式

第一行为一个整数 n n n

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

输出格式

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

样例 #1

样例输入 #1

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

样例输出 #1

9

提示

对于所有数据,有 1 ≤ n ≤ 6 × 1 0 3 1\le n\le 6\times 10^3 1n6×103 0 ≤ t 1 , t 2 , t 3 ≤ 5 0\le t_1,t_2,t_3\le 5 0t1,t2,t35

二、分析

1、状态表示

f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示,分配前 i i i个任务,A机器上花费的时间是 j j j,B机器上花费的时间是 k k k,我们的 f f f数组是一个 b o o l bool bool数组,即判断这种方案是否存在。

那么我们求最终的答案呢?当我们求出所有状态后,只需要贪心地从小到大枚举判断当前方案是否存在即可。

但是这种三维DP明显超时了,空间也超了。所以,我们需要对这种定义方式进行优化。

f [ i ] [ j ] f[i][j] f[i][j]表示分配前 i i i个任务,机器 A A A上的时间是 j j j f f f数组存储的是在 A A A分配 j j j时间的条件下,我们的 B B B机器分配的最短时间。最后贪心枚举判断一下即可。

这里告诉我们的经验就是:当题目中有多个限制条件的时候,我们可以考虑将其中一个限制转化为状态中的一个维度。

2、状态转移

这里的状态转移采用了背包问题的思想。
我们针对第 i i i个物品的分配方式进行讨论。
在题目允许的情况下, 要么分配给 A A A,要么分配给 B B B,要么分配给 A + B A+B A+B
f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ i − 1 ] [ j − t a ] ) f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ i − 1 ] [ j ] + t b ) f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ i − 1 ] [ j − t a b ] + t a b ) f[i][j]=min(f[i][j],f[i-1][j-t_a])\\ f[i][j]=min(f[i][j],f[i-1][j]+t_b) \\f[i][j]=min(f[i][j],f[i-1][j-t_{ab}]+t_{ab}) f[i][j]=min(f[i][j],f[i1][jta])f[i][j]=min(f[i][j],f[i1][j]+tb)f[i][j]=min(f[i][j],f[i1][jtab]+tab)

3、空间优化

因为我们只用到了第 i − 1 i-1 i1层的信息,所以我们需要用滚动数组。因为我们求的是最小值,当我们滚到某一层时,需要先将这一层初始化为 I N F INF INF。避免之前遗留的状态影响到当前的转移。

在洛谷提交需要开 O 2 O2 O2

三、代码

#include<bits/stdc++.h>
#define endl '\n'
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 6e3 + 10;
int a[N], b[N], c[N];
int n;
int f[3][N * 5];
void solve()
{
	cin >> n;
	for(int i = 1; i <= n; i ++ )
		cin >> a[i] >> b[i] >> c[i];

	memset(f, INF, sizeof f);
	f[0][0] = 0;
	for(int i = 1; i <= n; i ++ )
	{
		memset(f[i & 1], INF, sizeof f[i & 1]);
		for(int j = 0; j <= 5 * n; j ++ )
		{
			if(a[i] && j >= a[i])
				f[i & 1][j] = min(f[(i - 1) & 1][j - a[i]], f[i & 1][j]);
			if(b[i])
				f[i & 1][j] = min(f[(i - 1) & 1][j] + b[i], f[i & 1][j]);
			if(c[i] && j >= c[i])
				f[i & 1][j] = min(f[(i - 1) & 1][j - c[i]] + c[i], f[i & 1][j]);
		}	
	}


	int minv = INF;
	for(int i = 0; i <= 5 * n; i ++ )
		minv = min(minv,max(i, f[n & 1][i]));

	cout << minv << endl;
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	solve();
}

http://www.kler.cn/a/15147.html

相关文章:

  • PHP开发全新UI多语言多商户跨境商城源码、支持一键铺货、一键下单
  • 模式:每个服务一个数据库
  • 剧本杀门店预约小程序,解锁沉浸式推理体验
  • 【计算机网络】水平触发与边缘触发有什么优缺点呢?
  • Linux :进程间通信之管道
  • Http常⻅见请求/响应头content-type内容类型讲解(笔记)
  • Cell Reports:任栓成/高东/胡志安/唐玲团队合作揭示压力性失眠发生的神经机制
  • SpringBoot -02 SpringBoot整合Mybatis、Druid数据源、单元测试、JSP
  • 最近部门新的00后真是卷王,工作没1年,入职18K
  • AlgoC++第六课:BP反向传播算法
  • SSL证书的五大优势
  • nssctf web
  • TOMCAT NGINX 环境的搭建脚本
  • 【华为校招真题】分配资源ID 100% C++
  • Python中 re.findAll()、re.sub()、set()的使用
  • 轻量级服务器nginx:负载均衡
  • 郑哲:学习、应用初探与探索创新 | 提升之路系列(四)
  • 【Linux】项目自动化构建工具-make/Makefile
  • 【Git 入门教程】第三节、Git的分支和合并
  • 山路转债上市价格预测
  • Sample语言上下文无关文法
  • SpringBoot操作Mongodb
  • Vue进阶-Vue cli项目搭建、项目基本操作、axios的使用、路由、Vuex
  • SpringBoot 中如何正确的实现模块日志入库?
  • 视频可视化搭建项目,通过简单拖拽方式快速生产一个短视频
  • 光波导相控阵技术