题目传送门

Description
有个国有中型企业,接到一批需要加工零件的订单,员工们非常高兴,工厂领导为了鼓
励员工尽快地完成加工任务,出台了奖励政策:“如果在保证质量要求的前提下,每完成
一个零件加工任务,都有相同数量的奖金!”。所以所有员工都希望加工尽量多的零件,
以便拿到更多的奖金。现在请你帮忙,怎样加工才能在一台机床上加工最多的零件。假定对于待加工的第i个零件,给你两个非负整数Si,Ei,其中Si表示加工开始的时间,
其中Ei表示加工结束的时间,由于受到客观条件的制约,这开始和结束的时间限制必须
要遵守。当然在某个时刻一台机器只能加工一个零件。Input
本问题有多组测试数据,对于每组测试数据,输入的第一行是三个非负的整数N
(0<=N<=1000),TB,TE(0<=TB<=TE<=10000),其中N表示需要加工的零件个
数,TB和TE分别表示给定的时间范围,即要求在TB和TE的时间内加工尽量多的零件。
接着是N行[Si,Ei],其中Si,Ei如上所述(0<=Si<=Ei<=10000),而且规定零件编号顺
序
就是输入的顺序。Output
输出只有一行就是能够加工的最多的零件数;Sample Input
7 0 10
[4,7]
[2,5]
[1,3]
[7,8]
[3,7]
[1,4]
[6,9]
Sample Output
3
Author
CML

解法一:建立DAG求最长路径

假设已建立出有向无环图(DAG),那么可以用拓扑排序+松弛操作求解最长路径(单源最长路径)。考虑如何建图:一个合法的订单(在规定时间内的订单)就是图上的一个点,对于一条有向边X->Y,表示订单X做完以后接着再做Y订单。对于图上一条路径,就能代表一种解决方案,比如 a->b->c->d(路径长度为3),就代表依次完成a,b,c,d四个订单。不难发现,订单数(即点数)是边数(即路径长度)+1。题目求的是最多能完成的订单数,对应的也就是最长路径+1。再次考虑有向边X->Y,它代表订单X做完以后接着再做Y订单,根据题目要求,同一时刻只能有一台机器工作,也就是订单之间不能有时间上的重合。比如【3,5】和【4,6】有重合,不合法。而【3,5】和【7,10】,没有重合,完全可以先做完【3,5】,再去完成【7,10】,那么就可以建立有向边X【3,5】->Y【7,10】。

还有一个问题需要解决:如何选择单源最长路的源点(起点)。暴力一点的话,不妨直接枚举,尝试将每个合法订单作为第一个完成的订单(即最长路的起点),在n条不同起点的最长路中,再取最长的一条。思考到这里,已经可以求出正确答案了,不过还需要考量一下该做法的时间复杂度是否可承受。一次最长路的时间复杂度即一次拓扑排序的时间复杂度,是O(n+m)的,其中n是DAG点数,m是边数。本题边数的数量级是( n2n^2n2) 的, 所以求解一次最长路是O( n2n^2n2),又需要跑n次最长路,所以总体时间复杂度达到了O(n3n^3n3)本题n的范围给到了 1000。n3n^3n3=1e9这个时间复杂度无法承受。

有没有方法避免枚举起点(跑n次最长路)呢?,。答案是有的,实际上,可以只跑一次最长路就获得全局最长路。考虑建立一个虚拟的超级起点(或者说一个虚拟订单),我们总是先去完成这个虚拟的超级订单,再考虑其他订单,即从这个超级起点向所有订单分别 连出一条有向边,代表完成了超级订单之后,下一个订单可以是任意一个订单。(在效果上相当于枚举了最长路的起点)。这样时间复杂度降到了O(n^2) 需要注意的是,超级订单是虚拟的,并不存在 ,最终要减去它的贡献,所以最终答案是 (最长路径长度+1-1)=最长路径。

#include<bits/stdc++.h>
using namespace std;
struct order
{int l, r;
};
const int MAXN = 1e3 + 10;
order a[MAXN];
//链式前向星 存图
struct EDGE {int to;int nex;
}E[MAXN * MAXN];
int head[MAXN];
int tot = 0;
inline void add(int u, int v)
{E[++tot].to = v;E[tot].nex = head[u];head[u] = tot;
}
//-----------------------------------
const int INF = 1e9;
bool vis[MAXN];
int dis[MAXN];
int in[MAXN];
int topu(int st, int n)//拓扑排序 +类松弛操作 (松弛似乎就是DP的思想~)
{for (int i = 0; i <= n; i++)dis[i] = -INF, vis[i] = 0;dis[st] = 0;queue<int>q;q.push(st);while (!q.empty()){int u = q.front();q.pop();if (vis[u])continue;vis[u] = true;for (int i = head[u]; i; i = E[i].nex){int v = E[i].to;if (dis[v] < dis[u] + 1) {//类似最短路算法的松弛dis[v] = dis[u] + 1;}in[v]--;if (in[v] == 0) {//入度为零,可以入队q.push(v);}}}int ans = 0;for (int i = 0; i <= n; i++)if (ans < dis[i])ans = dis[i];return ans;
}
int n, TS, TE,cnt;
inline void init(int n) {//初始化cnt = 0;//合法订单数量tot = 0;//DAG 边数for (int i = 0; i <= n; i++)head[i] = 0, in[i] = 0;
}
int main()
{while (~scanf("%d %d %d", &n, &TS, &TE)){init(n);for (int i = 1; i <= n; i++){int l, r;scanf("\n[%d,%d]", &l, &r);if (l<TS || r>TE)continue;//不合法的订单,直接跳过a[++cnt].l = l;a[cnt].r = r;}sort(a + 1, a + 1 + cnt, [](const order& fi, const order& se) {return fi.r < se.r;});//按照订单的完成时间 排序for (int i = 1; i <= cnt; i++){for (int j = 0; j < i; j++){if (a[i].l >= a[j].r &&a[i].r>a[j].r ) {//两个订单时间上无重合,允许先做j,在做i //则建立有向边 j->i  add(j, i);in[i]++;//入度}}}printf("%d\n", topu(0,cnt)+1-1);//个人认为+1-1 是有必要的,程序可读性会好一点//+1是因为对于一条路径来说,点数=边数+1,最长路的结果是边数,而求得是点数(订单数)//-1是因为我们加入了虚拟的超级起点(避免了真实起点的枚举),所以要减去它的贡献}return 0;
}

解法二:动态规划(DP)

虽然做法不一样,但在思想上和解法一差不多。考虑订单之间如何转移。对于一个订单,总是从在它之前完成的那些订单转移过来(所以和解法一 一样,也先排个序)。
DP【i】代表以第i个订单作为最后一个完成的订单时,能完成的最多订单数

#include<bits/stdc++.h>
using namespace std;
struct node
{int l, r;
};
const int MAXN = 1e3 + 10;
node a[MAXN];
int dp[MAXN];
int main()
{int n, TS, TE;while (~scanf("%d %d %d", &n, &TS, &TE)){int tot = 0;for (int i = 1; i <= n; i++){dp[i] = 0;int l, r;scanf(" [%d,%d]", &l, &r);if (l<TS || r>TE)continue;a[++tot].l = l;a[tot].r = r;}sort(a + 1, a + 1 + tot, [](const node& fi, const node& se) {return fi.r < se.r;});int ans = 0;for (int i = 1; i <= tot; i++){for (int j = 0; j < i; j++){if(a[i].l>=a[j].r && a[i].r>a[j].r)dp[i] = max(dp[i], dp[j] + 1);}ans = max(dp[i], ans);}printf("%d\n", ans);}return 0;
}

AOJ 15951 零件加工问题二相关推荐

  1. HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格

    HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格 示例程序源码(加注释) 关于显示类函数解释 dev_update_off () Imag ...

  2. 拨叉零件加工工艺及钻18孔夹具设计(说明书+CAD图纸+solidworks三维图+工序卡+过程卡)

    摘  要 本次设计内容涉及了机械制造工艺及机床夹具设计.金属切削机床.公差配合与测量等多方面的知识. 弯臂加工工艺规程及钻孔的夹具设计是包括零件加工的工艺设计.工序设计以及专用夹具的设计三部分.在工艺 ...

  3. K626-弯臂拨叉零件加工工艺及钻Φ18孔夹具设计(说明书+CAD图纸+SW三维图+工序卡+过程卡)

    摘  要 本次设计内容涉及了机械制造工艺及机床夹具设计.金属切削机床.公差配合与测量等多方面的知识. 弯臂加工工艺规程及钻孔的夹具设计是包括零件加工的工艺设计.工序设计以及专用夹具的设计三部分.在工艺 ...

  4. K626-弯臂拨叉零件加工工艺及钻18孔夹具设计(说明书+CAD图纸+solidworks三维图+工序卡+过程卡)

    摘  要 本次设计内容涉及了机械制造工艺及机床夹具设计.金属切削机床.公差配合与测量等多方面的知识. 弯臂加工工艺规程及钻孔的夹具设计是包括零件加工的工艺设计.工序设计以及专用夹具的设计三部分.在工艺 ...

  5. 如何解决编程的误差问题_柏威机械丨高精密零件加工是如何解决误差精度问题的?...

    机械的快速发展,对于设备零件的精度就有了更高的要求,而高精度的零件加工需求,就需要广东零件加工企业(柏威机械)对加工工艺进行改进. 机械加工工艺是根据图纸对零件进行加工的过程,加工工艺不止一种,对于一 ...

  6. 零件加工 贪心 题解

    1019: B06-贪心-零件加工[提高组] 时间限制: 1 Sec  内存限制: 128 MB 提交: 24  解决: 7 [提交] [状态] [讨论版] [命题人:外部导入] 题目描述 工匠小K最 ...

  7. C++——NOIP模拟题——零件加工

    零件加工 题目描述 工匠小 K 最近有 n 个零件需要加工.每个零件都需要 ti 天的时间来完成,每个零件每延迟一天加工都要缴纳一定的罚金 si .延迟的天数为从今天算起到该工作开始的那天,第一个零件 ...

  8. 车床零件加工调度问题

    目录 题目 思路 代码 运行结果 题目 某车间需要用一台车床和一台×××加工A,B,C,D4个零件.每个零件都需要先用车床加工,再用×××加工.车床和×××加工每个零件所需的工时(包括加工前的准备时间 ...

  9. UGNXCAM加工模块二次开发视频教程全集(全套视频教程)_NXopen-UG二次开发_新浪博客

    UG NX CAM 加工模块二次开发视频教程全集(胡君录制) 教程简介: 本套 NX CAM 加工模块二次开发视频教程由胡君录制,教程详细的讲解了关于NX加工模块开发的各个知识点,以及同时使用UFun ...

最新文章

  1. 计算机图形学直线扫描转论文,计算机图形学实验报告-实验1直线段扫描转换.doc...
  2. JTAG error:can not read register while CPU is running该如何解决
  3. 【深度学习入门到精通系列】关于梯度下降和反向传播的探索
  4. python循环实验心得_2019.06.18学习python循环总结
  5. ubuntu 16.04 安装MXNet GPU版本
  6. springboot主线程_Springboot对多线程的支持详解
  7. php $start_date-sub(,PHP DateTime类常用方法总结
  8. 哪个内存更快?Heap或ByteBuffer或Direct?
  9. LeetCode 333. 最大 BST 子树(递归)*
  10. 【Python】pdfminer3k模块批量转换本地PDF文件
  11. 云计算底层技术--linux上的虚拟网络设备
  12. 在Windows 7中搭建Wordpress环境
  13. 单片机实验13:用热敏电阻和ADC实现测量温度
  14. poe工业以太网交换机可以当普通交换机用吗,poe工业以太网交换机有哪些优势
  15. 多线程通信Queue
  16. 图像的基本运算——scale, rotation, translation
  17. 048python写字笔画顺序识别检测笔顺是否有误检测
  18. js访问对方手机文件夹_Javascript读取某文件夹下的所有文件
  19. vue项目对接pad端——混合开发总结
  20. 设计模式——结构型模式

热门文章

  1. 基本IO接口技术——微机第七章笔记
  2. Arthur van Hoff
  3. 【Windows】win10多桌面与多任务
  4. jit和jitx区别_JIT的核心思想是什么?
  5. 【色彩管理】锐印添加ICC曲线教程
  6. html 中的push方法,push方法怎么使用
  7. QingCloud首届用户大会亮点抢先看
  8. html播放韰 寸 频,js根据文字获取首字母案例,直接复制在html中即可查看效果
  9. 【微信开放平台】微信第三方扫码登录(亲测可用)
  10. 在未提供官方驱动的Windows平板上安装Win10且完美驱动的解决方案