首页 > 系统相关 >多进程 DP

多进程 DP

时间:2024-10-17 21:10:54浏览次数:2  
标签:min int cost maxn 进程 day DP

我好像还没怎么见过这样的题。 不过,做任何 DP,深刻充分的理解永远是通用的题解。

例子

有两个对象,共同完成一批任务,其中一个对象做任务时,另一个对象可以在同时完成别的任务;对于每个任务,两对象完成的时间不同,求最快什么时候完成。

看看例题

  1. P2224 HNOI2001 产品加工 - 洛谷

分析

令 \(f[i][j]\) 表示做到第 \(i\) 件物品,机器 \(A\) 耗时为 \(j\) 时,\(B\) 机器所耗费的最短时间。 设 \(t[i][0/1/2]\) 表示第 \(i\) 件物品由 \(A\),\(B\),或 \(A, B\) 共同加工的时间,则:

\[\begin{aligned} f[i][j] = min\{f[i - 1][j - t[i][0]], f[i - 1][j] + t[i][1], f[i - 1][j - t[i][2]] + t[i][2]\}\\ \end{aligned} \]

\(f[i - 1][j - t[i][0]]\) 表示这个任务由 \(A\) 完成。

\(f[i - 1][j] + t[i][1]\) 表示这个任务由 \(B\) 完成。

\(f[i - 1][j - t[i][2]] + t[i][2]\) 表示这个任务由 \(A, B\) 共同完成。

初始化:\(f[0][0] = 0\),其他均设为正无穷。

本题数据范围比较大,二维数组空间过大,所以要用滚动数组滚掉一维。(滚动数组注意当前状态的含义与合法性)

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 6e3 + 5;
int f[maxn * 5];
int n;
int cost[maxn][3];
int up;

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j < 3; j++) {
			scanf("%d", &cost[i][j]);
		}
		up += max(cost[i][0], max(cost[i][1], cost[i][2])); // 记录完成时间的上界
	}
	memset(f, 0x3f, sizeof(f));
	f[0] = 0;
	// f[i][j] = min{ f[i - 1][j - cost[i][0]], f[i - 1][j] + cost[i][1], f[i - 1][j - cost[i][2]] + cost[i][2] }
	for (int i = 1; i <= n; i++) {
		for (int j = up; j >= 0; j--) {
			int temp = f[j]; // 要注意的地方:f[j] 发生了变化,所以要暂存下来参与决策。  
			f[j] = 0x3f3f3f3f; //相当于每次初始化
			if (cost[i][0] && j >= cost[i][0]) {
				f[j] = min(f[j], f[j - cost[i][0]]);
			}
			if (cost[i][1]) {
				f[j] = min(f[j], temp + cost[i][1]); // here is temp.
			}
			if (cost[i][2] && j >= cost[i][2]) {
				f[j] = min(f[j], f[j - cost[i][2]] + cost[i][2]);
			}
		}
	}
	int ans = 0x3f3f3f3f;
	for (int i = 0; i <= up; i++) {
		ans = min(ans, max(f[i], i)); // 完成时间为 A, B 中较大的那个
	}
	printf("%d", ans);
	return 0;
}
  1. P1800 software - 洛谷

分析

和上一道题比较类似,但又不太一样。

首先可以发现,交付时间为两个软件完成时间较长的那个,而我们要求这个较长的时间最短——二分答案!

然后我们就二分交付时间,然后用 DP 检验这个时间是否合法。

设 \(f[i][j]\) 表示到第 \(i\) 个技术人员的时候,第一个软件已经完成了 \(j\) 个模块,第二个软件可以完成的模块数量,则:

\[\begin{aligned} f[i][j] = \max_{0 \le k \le min(\frac{day}{d1[i]}, j)}\{f[i - 1][j - k] + (\frac{day - d1[i] \times k}{d2[i]})\} \end{aligned} \]

其中 \(day\) 表示二分查找枚举的交付日期。

DP 完之后,若 \(f[m] \ge m\),则表示程序一做完 \(m\) 个模块的时候,程序二也至少能完成任务。

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 105;
int n, m;
int f[maxn];
int dev1[maxn], dev2[maxn];

bool check(int day) {
    f[0] = 0; // 滚动数组压维了
    for (int i = 1; i <= m; i++) {
        f[i] = -0x3f3f3f3f;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = m; j >= 0; j--) {
            for (int k = 0; k <= min(day / dev1[i], j); k++) {
                f[j] = max(f[j], f[j - k] + (day - k * dev1[i]) / dev2[i]);
            }
        }
    }
    return f[m] >= m;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &dev1[i], &dev2[i]);
    }
    int l = 0, r = 114514;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    printf("%d", l);
    return 0;
}

标签:min,int,cost,maxn,进程,day,DP
From: https://www.cnblogs.com/jxyanglinus/p/18473103

相关文章

  • 线程和进程解释和创建
    一、含义:进程:是系统进行资源分配和调用的独立单位,每一个进程都有它自己的内存空间和系统资源。举例:IDEA,阿里云盘,wegame,steam线程:是进程中的单个顺序控制流,是一条执行路径一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行路径,则称为多线程程序。......
  • 【状态机DP】力扣309. 买卖股票的最佳时机含冷冻期
    给定一个整数数组prices,其中第prices[i]表示第i天的股票价格。​设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):卖出股票后,你无法在第二天买入股票(即冷冻期为1天)。注意:你不能同时参与多笔交易(你必须在再次购......
  • 【状态机DP】【hard】力扣188. 买卖股票的最佳时机 IV
    给你一个整数数组prices和一个整数k,其中prices[i]是某支给定的股票在第i天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成k笔交易。也就是说,你最多可以买k次,卖k次。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例......
  • IO、进程/线程、同步/异步、阻塞/非阻塞
    IO(Input/Output)IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首......
  • dp一遍通
    前言马上csp-s考试了,却发现自己dp太菜了,打算恶补dp线性dp理解递推/记忆化搜索,有很多种理解方式递归重叠子问题的记忆化搜索:像这里例如\(f[3]\)可以通过一次计算得到,保存答案,下一次直接调用即可,省去很多复杂度我们从此引出dp第一个性质:最优子结构大问题的最优解包含小问......
  • P1880 [NOI1995] 石子合并 区间DP 记忆化DFS模拟DP
    P1880[NOI1995]石子合并诈骗题,看着像贪心,实际上是DP对贪心的hack:6346542如果使用贪心法求最小得分,应该是如下的合并步骤:第一次合并3465422,3合并得分是5第二次合并546545,4合并得分是9第三次合并96545,4合并得分是9......
  • 安防综合管理系统EasyCVR视频汇聚平台Linux环境,如何测试UDP端口是否开启?
    视频汇聚EasyCVR安防监控视频系统采用先进的网络传输技术,支持高清视频的接入和传输,能够满足大规模、高并发的远程监控需求。平台灵活性强,支持国标GB/T28181协议、部标JT808、GA/T1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石......
  • C# UDP通信 ReceiveAsync() 一直等待问题
    问题描述两个C#应用,一个作为服务端Server,另一个作为客户端Client,客户端打开一个Udp端口,循环接收数据;服务端开启后向客户端发送指令,当服务端出现异常时关闭了服务端的UdpClient,此时客户端卡死在_client.ReceiveAsync(),无法再接收到消息。客户端代码:try{varcts=newCanc......
  • 专项训练dp总结
    作者在做题的时候深感自己dp水平的低下(几近为零),于是尝试逼迫自己搞懂每道题并写一点做题记录,本质上是为了避免自己成为只会抄题解的机器。。1.[PA2021]Oddeskidodeski首先,对于一个合法的序列f,若f+x为合法序列,那么f+x+x必然也为合法序列。其次状态设计,设\(f_{i,j,0/1}\)......
  • 嵌入式学习-IO进程-Day03
    嵌入式学习-IO进程-Day03IO进程获取文件属性(stat)库库的概念库的分类静态库的制作动态库的制作进程进程和程序的区别进程的特点进程三段进程的类型进程的运行状态进程状态转换图(重点)进程的函数接口创建进程forkfork函数创建的子进程的特点IO进程获取文件......