洛谷 题解 P3161 【[CQOI2012]模拟工厂】
本蒟蒻又双叒叕被爆踩辣!
Solution:
这题又是一道贪心。。
数据范围:
n<=15 ti<=100,000 gi<=10^9 mi<=10^9
这里就可以看到几个小细节,也可以想出一些思路。
要开long long!
首先,n <= 15, 这个数据可以说是很小辣,它代表有n个任务,又因为
如果接受订单i,则必须恰好在时刻ti交易,不能早也不能晚。同一时刻可以接受多个订单,但每个订单只能被接受一次。
窝们本不知道选择哪些任务才会是利润最高,而且这很明显也无法通过一些规律来知道选择哪个会最优。
所以窝们应该怎么办???
枚举!!!
因为只有数据范围只有15,所以窝们可以枚举1到(1 << n) - 1用二进制表示当前这个任务选不选,那我们已经解决了这个任务辣!
接下来就是,然后处理每个任务方案。
窝们针对每个任务方案,依次判断它的可行性。
然后在可行的方案中找出利润最大的(就是保证任务完成的情况下,保证生产力更大。
假设窝们当前有那么对于订单i和j,我们都会得到方程:make为完成订单i时的生产力,time为距离j订单的时间,time_create为用来提升生产力的时间,need是订单j需求量
(make + time_create) × (time − time_create) = need
化简就是:
time_create * time_create + (make - time) * time_create + need - make * time = 0;
只要保证起“根的判别式” >= 0就行。
所以复杂度应该是O(2 的 n次方 * n 的平方);
具体见代码,这里只有一些思路,个人介意对着代码读,更容易理解
Code:
#include<bits/stdc++.h>
using namespace std;
#define maxn 25
#define maxm
#define ll long long//mi数据1e9,你不开longlong看看
#define int long long
#define Rep(x, a, b) for(int x = a; x <= b; ++ x)
#define Dep(x, a, b) for(int x = a; x >= b; -- x)
#define Next(x, u) for(int i = head[u]; i ; i = e[i].nxt)
//int read(){窝不喜欢用快读,但缺省源里面放了,所以也没删
// int f = 1, x = 0;
// char c = getchar();
// while(c < '0' || c > '9'){
// if(c == '-'){
// f = -1;
// }
// c = getchar();
// }
// while(c >= '0' && c <= '9'){
// x = (x << 1) + (x << 3) + (c ^ 48);
// c = getchar();
// }
// return x * f;
//}
struct node{
int t, g, m;//都如题,t是在什么时刻交易,g是需要多少货,m是可以得到的利润
}e[maxn], s[maxn];
//e是记录所有的任务
//s是记录当前情况窝们已经选择的任务
int n, ans;//不多说
bool cmp(node x, node y){
return x.t < y.t;
}//要先按照t排序,要不不好处理
int discriminant(int b, int c){//这个单词是“判别式”,百度说的
if(b * b - 4 * c < 0){//都知道二次函数根的判别式吧(b * b - 4 * a * c)
return -1;//返回-1,即根的判别式小于0
}
return floor((-b + sqrt(b * b - 4 * c)) / 2);//否则就返回它的根:((-b + sqrt(b * b - 4 * a * c) / 2 / a)
}
void dfs(int x){
int now_have = 0, make_force = 1, ans_now = 0, tot = 0;
//now_have是窝们当前拥有的货物
//make_force是当前的生产力
//ans_now是这种方案的利润
//tot是当前这种选择方案任务的个数
Rep(i, 1, n){//这里就是寻找当前方案的任务
if(x & (1 << i - 1)){//用二进制
s[++ tot] = e[i];//进入s
ans_now += e[i].m;//就是当前方案的总利润
}
}
Rep(i, 1, tot){
int t = s[i].t - s[i - 1].t, sum = 0;//sum是所需要的货物
//t是时间,s[i].t - s[i- 1].t是它的最大值,因为当它前面的货物足够购买这两个货物时,它的t就是此值
Rep(j, i, tot){//算t的值
sum += s[j].g;//累加所需要的货物
if(now_have >= sum){//如果货物还够,那就下一层循环
continue;
}//否则,就更新t,为t,和它的根的最小值
t = min(t, discriminant(make_force - s[j].t + s[i - 1].t, sum - now_have - make_force * (s[j].t - s[i - 1].t)));
}
if(t < 0){//如果无法完成次方案
return;//return
}
make_force += t;//生产力就要加,(尽可能加就行
now_have += make_force * (s[i].t - s[i - 1].t - t) - s[i].g;//其余就现在有的产量
}
ans = max(ans, ans_now);//更新值
}
signed main(){
scanf("%lld", &n);//输入
Rep(i, 1, n){//输入每个任务
scanf("%lld%lld%lld", &e[i].t, &e[i].g, &e[i].m);
}
sort(e + 1, e + n + 1, cmp);//按时刻排序
Rep(i, 0, (1 << n) - 1){
dfs(i);//每种方案跑一遍
}
printf("%lld", ans);//输出
return 0;
}
下面还给两组数据
Inout:
5
5 5 5
7 7 7
9 9 9
11 1 15
16 18 778
Output:
814
Input:
10
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
9 9 9
10 10 10
Output:
30
Ps:请看懂再抄
洛谷 题解 P3161 【[CQOI2012]模拟工厂】的更多相关文章
- P3161 [CQOI2012]模拟工厂
传送门 先枚举选择哪些订单,然后转为判定是否可行 在能完成的情况下肯定是花越多时间提高生产力越优 我们设可以有\(x\)单位时间来提高生产力,那么如果当前离下一个订单的时间为\(T\)时,这个订单要\ ...
- LUOGU P3161 [CQOI2012]模拟工厂 (贪心)
传送门 解题思路 贪心,首先因为\(n\)比较小,可以\(2^n\)枚举子集.然后判断的时候就每次看后面的如果用最大生产力生产能不能达成目标,解一个二次函数. 代码 #include<iostr ...
- [CQOI2012]模拟工厂 题解(搜索+贪心)
[CQOI2012]模拟工厂 题解(搜索+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327574 链接题目地址:洛谷P3161 BZOJ P26 ...
- [BZOJ2667][cqoi2012]模拟工厂
[BZOJ2667][cqoi2012]模拟工厂 试题描述 有一个称为“模拟工厂”的游戏是这样的:在时刻0,工厂的生产力等于1.在每个时刻,你可以提高生产力或者生产商品.如果选择提高生产力,在下一个时 ...
- [BZOJ2667][cqoi2012]模拟工厂 贪心
2667: [cqoi2012]模拟工厂 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 367 Solved: 184[Submit][Status] ...
- 洛谷 题解 UVA572 【油田 Oil Deposits】
这是我在洛谷上的第一篇题解!!!!!!!! 这个其实很简单的 我是一只卡在了结束条件这里所以一直听取WA声一片,详细解释代码里见 #include<iostream> #include&l ...
- 洛谷P1667/[10.22 模拟赛] 数列 (思维+模拟)
洛谷P1667 数列 题目描述 给定一个长度是n的数列A,我们称一个数列是完美的,当且仅当对于其任意连续子序列的和都是正的.现在你有一个操作可以改变数列,选择一个区间[X,Y]满足\(A_X +A_{ ...
- 洛谷 题解 P1600 【天天爱跑步】 (NOIP2016)
必须得说,这是一道难题(尤其对于我这样普及组205分的蒟蒻) 提交结果(NOIP2016 天天爱跑步): OJ名 编号 题目 状态 分数 总时间 内存 代码 / 答案文件 提交者 提交时间 Libre ...
- 洛谷题解P4314CPU监控--线段树
题目链接 https://www.luogu.org/problemnew/show/P4314 https://www.lydsy.com/JudgeOnline/problem.php?id=30 ...
随机推荐
- python学习之【第八篇】:Python中的函数基础
1.前言 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 2.函数的定义 定义函数时需要遵守以下规则: 函数代码块以 def 关键词开头 ...
- Flink入门(一)——Apache Flink介绍
Apache Flink是什么? 在当代数据量激增的时代,各种业务场景都有大量的业务数据产生,对于这些不断产生的数据应该如何进行有效的处理,成为当下大多数公司所面临的问题.随着雅虎对hadoop的 ...
- 深入理解计算机系统 第三章 程序的机器级表示 part2
这周由于时间和精力有限,只读一小节:3.4.4 压入和弹出栈数据 栈是一种特殊的数据结构,遵循“后进先出”的原则,可以用数组实现,总是从数组的一端插入和删除元素,这一端被称为栈顶. 栈有两个常用指令 ...
- springboot使用dubbo和zookeeper
2019-11-17 yls 创建服务接口模块 接口工程只提供接口,不提供实现,在后面的提供者和消费者中使用 在使用接口的模块中只需要写具体实现类,避免了在每个模块中重复编写接口 在接口中引入依赖包 ...
- 物联网安全himqtt防火墙数据结构之红黑树源码分析
物联网安全himqtt防火墙数据结构之红黑树源码分析 随着5G的发展,物联网安全显得特别重要,himqtt是首款完整源码的高性能MQTT物联网防火墙 - MQTT Application FireWa ...
- C++中对封装的语法支持——重载运算符
重载运算符 1.对于自定义类型,编译器不知道运算规则,而重载运算符会将两个对象相加转换为函数调用. 2.运算符重载转换的函数调用,函数名字是固定的规则. (1) 如果重载+号运算符,函数名字就是:op ...
- PHP 当Swoole 遇上 ThinkPHP5
本文假设你已经有了 Linux 操作系统的 PHP 环境,强烈推荐使用 Vagrant 来搭建开发环境 安装 Swoole PECL 拓展可以通过 pecl 命令或者通过源码包编译安装,本文采用 pe ...
- Salesforce学习之路(十)Org的命名空间
1. 命名空间的适用场景 每个组件都是命名空间的一部分,如果Org中设置了命名空间前缀,那么需使用该命名空间访问组件.否则,使用默认命名空间访问组件,系统默认的命名空间为“c”. 如果Org没有创建命 ...
- nyoj 71-独木舟上的旅行(贪心)
71-独木舟上的旅行 内存限制:64MB 时间限制:3000ms 特判: No 通过数:10 提交数:15 难度:2 题目描述: 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别.一条 ...
- 【并发编程】Java中的原子操作
什么是原子操作 原子操作是指一个或者多个不可再分割的操作.这些操作的执行顺序不能被打乱,这些步骤也不可以被切割而只执行其中的一部分(不可中断性).举个列子: //就是一个原子操作 int i = 1; ...