[一本通1677/JZOJ1217/CJOJ1101]软件开发 题解
题目描述
一个软件开发公司同时要开发两个软件,并且要同时交付给用户,现在公司为了尽快完成这一任务,将每个软件划分成\(m\)个模块,由公司里的技术人员分工完成,每个技术人员完成同一软件的不同模块的所用的天数是相同的,并且是已知的,但完成不同软件的一个模块的时间是不同的,每个技术人员在同一时刻只能做一个模块,一个模块只能由一个人独立完成而不能由多人协同完成。一个技术人员在整个开发期内完成一个模块以后可以接着做任一软件的任一模块。写一个程序,求出公司最早能在什么时候交付软件。
输入
输入文件第一行包含两个由空格隔开的整数\(n\)和\(m\)。
接下来的\(n\)行每行包含两个用空格隔开的整数\(d_1\)和\(d_2\),\(d_1\)表示该技术人员完成第一个软件中的一个模块所需的天数,\(d_2\)表示该技术人员完成第二个软件中的一个模块所需的天数。
输出
输出文件仅有一行包含一个整数\(d\),表示公司最早能于\(d\)天后交付软件。
输入样例
1 1
2 4
1 6
输出样例
18
提示
数据规模
对于100%的数据,\(1≤n≤100,1≤m≤100,1≤d_1,d_2≤100\)。
样例说明
最快的方案是第一个技术人员完成第二个软件的\(18\)个模块,用时\(18\)天,第三个技术人员完成第一个软件的\(18\)个模块,用时\(18\)天,其余的模块由第二个技术人员完成,用时\(12\)天,做完所有的模块需要\(18\)天。如果第一个技术人员完成第二个软件的\(17\)个模块,第三个技术人员完成第一个软件的\(17\)个模块,其余的模块由第二个技术人员完成,需要用时\(18\)天,做完所有模块仍然需要\(18\)天,所以少于\(18\)天不可能做完所有模块。
思路
这个完成天数可能否完成存在一个线性关系,所以这肯定是到二分答案的题目。问题在于如何进行判断能否完成。
首先假设 \(f_{i,j}\)表示到第\(i\)个技术人员的时候,第一个软件已经完成了\(j\)个模块,第二个软件可以完成的模块数量。先给出状态转移方程
\[f_{i,j}=\underset{0\le k \le min{\left [\frac{day}{d_{1,i}}\right ] }}{\text max} \left \{ f_{i-1,j-k}+\left [ \frac{day-k\times d_{1,i}}{d_{2,i}} \right ] \right \}
\]
其中\(day\)表示二分的天数,\(k\)表示\(i\)个人抽出做程序1去做程序2的时间。
最终如果\(f_m\ge m\),那么就可以在 \(day\) 天完成这两个项目。
时间复杂度为 \(O(n\times m^2 \times log m)\)
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 102;
int d1[N];
int d2[N];
int n, m;
int f[N];
inline bool check(int day)
{
f[0] = 0;
for (int i = 1; i <= m; i++)
f[i] = -1e9; //要保证 程序1 的 i个模块一定做的完,那就让 做 程序1 的 i个模块 时 程序2 什么都不要做
for (int i = 1; i <= n; i++) //枚举每个人
for (int j = m; j >= 0; j--) //能够完成 软件1 m个模块时候
for (int k = 0; k <= min(day / d1[i], j); k++) //现在第i个人选择抽出做 软件1 k个模块的时间,来做 软件2
f[j] = max(f[j], f[j - k] + (day - d1[i] * k) / d2[i]);
return f[m] >= m; //程序1 做 m个模块的时候,程序2 也至少能完成任务
}
int main()
{
int l = 1, r = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++)
{
scanf(" %d %d", &d1[i], &d2[i]);
r = max(r, m * d1[i]);
r = max(r, m * d2[i]);
}
while (l < r)
{
int mid = l + r >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
printf("%d", r);
return 0;
}
[一本通1677/JZOJ1217/CJOJ1101]软件开发 题解的更多相关文章
- 【BZOJ】1221: [HNOI2001] 软件开发(最小费用最大流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1221 先吐槽一下,数组依旧开小了RE:在spfa中用了memset和<queue>的版本 ...
- [HNOI 2001]软件开发
Description 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员 ...
- bzoj 1221 [HNOI2001] 软件开发 费用流
[HNOI2001] 软件开发 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1938 Solved: 1118[Submit][Status][D ...
- 【bzoj1221】[HNOI2001] 软件开发 费用流
题目描述 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消 ...
- BZOJ1221 [HNOI2001] 软件开发 【费用流】
题目 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供一块消毒毛 ...
- BZOJ 1221 [HNOI2001] 软件开发 费用流_建模
题目描述: 某软件公司正在规划一项n天的软件开发计划,根据开发计划第i天需要ni个软件开发人员,为了提高软件开发人员的效率,公司给软件人员提供了很多的服务,其中一项服务就是要为每个开发人员每天提供 ...
- nw.js桌面软件开发系列 第0.1节 HTML5和桌面软件开发的碰撞
第0.1节 HTML5和桌面软件开发的碰撞 当我们谈论桌面软件开发技术的时候,你会想到什么?如果不对技术本身进行更为深入的探讨,在我的世界里,有这么多技术概念可以被罗列出来(请原谅我本质上是一个Win ...
- 敏捷软件开发VS传统软件工程
敏捷软件开发:又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的一些新兴软件开发方法,是一种应对快速变化的需求的一种软件开发能力. 与传统软件工程相比,它们的具体名称.理念.过程.术语都不尽相同 ...
- Atitit.软件开发的三层结构isv金字塔模型
Atitit.软件开发的三层结构isv金字塔模型 第一层,Implements 层,着重与功能的实现.. 第二次,spec层,理论层,设计规范,接口,等.流程.方法论 顶层,val层,价值观层,原则, ...
- BZOJ 1221: [HNOI2001] 软件开发
1221: [HNOI2001] 软件开发 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1428 Solved: 791[Submit][Stat ...
随机推荐
- 记录一个错误:Traceback (most recent call last): from pip._internal.cli.main import main ImportError: No module named pip._internal.cli.main
问题描述 在安装yaml时得到报错如下 root@ag-virtual-machine:/home/ag/test_script# pip install pyyaml Traceback (most ...
- 【Azure 应用服务】App Service for Linux环境中,如何解决字体文件缺失的情况
问题描述 部署在App Service for Linux环境中的Web App.出现了字体文件缺失的问题,页面显示本来时中文的地方,区别变为方框占位. 问题分析 在应用中,通常涉及到显示问题的有两个 ...
- elementPlus使用el-icon
按着文档来撒 yarn add @element-plus/icons-vue main.ts import * as ElementIcons from '@element-plus/icons-v ...
- C++学习笔记之进阶编程
目录 进阶编程 STL(Standard Template Library) 容器(container) 仿函数(functor) 算法(algorithm) transform 查找 全排列 迭代器 ...
- WPF之认识XAML
目录 新建项目 剖析XAML代码 参考资料 新建项目 在Visual Studio 2019中使用WPF项目模板建立一个最简单的WPF项目,如下图所示: 可以看到,项目里面主要有两个分支: App.x ...
- GoFrame 优化接口的错误码和异常的思路
前言 你是否想在使用 GoFrame 的过程中,拥有一个能打印异常堆栈,能自定义响应状态码,能统一处理响应数据的接口.如果你回答是,那么,请耐心看完本文,或许会对你有所启发.若文中由表达不当之处,恳请 ...
- manjaroLinux-xfce4设置显示桌面快捷键
1.打开窗口快捷键 2.寻找显示桌面 3.设置快捷键 啊!简单的我都不想写了,这不是为让像以前的"我"--小白,食用性更好一点吗?
- 自我总结的git的使用
git是什么 git是一个分布式版本控制工具,github是代码托管平台. git有什么用 保存文件的所有修改记录 使用版本号进行区分 随时可浏览历史版本记录 可还原到历史指定版本 对比不同版本的文件 ...
- [.NET项目实战] Elsa开源工作流组件应用(一): Elsa工作流简介
Elsa工作流简介 工作流是什么? 引用维基百科中对工作流的解释: 是对工作流程及其各操作步骤之间业务规则的抽象.概括.描述.工作流建模,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以 ...
- Flutter如何状态管理
目录介绍 01.什么是状态管理 02.状态管理方案分类 03.状态管理使用场景 04.Widget管理自己的状态 05.Widget管理子Widget状态 06.简单混合管理状态 07.全局状态如何管 ...