[CQOI2012]组装 贪心
[CQOI2012]组装
首先有一个必须要能推的式子:设第\(i\)种零件选的生产车间位置为\(x _ i\),组装车间位置为\(x\), 则总的花费为
\]
\]
这是一个关于\(x\)的二次函数, 在\(x = \frac {\sum \limits _{i = 1} ^n x_i}{n}\)时取得最小值\(\sum \limits _{i = 1} ^ n x _ i ^ 2 - \frac {\sum \limits _{i = 1} ^ n x _ i} {n}\)。做到这步,我们就可以获得前40分,只需要枚举每种零件选的生产车间,复杂度是指数级的。考虑贪心优化枚举的过程。
下面为了表述方便,设\(o = \sum \limits _ {i = 1} ^ n x _ i ^ 2\),\(e = \sum \limits _{i = 1} ^ n x _ i\)。
首先我们对于同一种零件的生产车间按坐标从小到大排序,每次枚举把某种零件的生产车间替换成他的下一个,这样是有一些情况枚举不到的,但事实上我们只要保证可能的情况都枚举到了就行了,于是贪心.
先给出贪心的结论:设一次替换用一个二元组\(\{x _ i, y _ i\}(x_i < y_i)\)来表示,如果我们先把表示替换的二元组按照\(x _ i + y _ i\)从小到大排序,这样就一定不会错过最优解。
下面证明这个结论:用反证法,假设我们这样做会错过最优解,那么一定存在\(\{x_1, y_1\}\)和\(\{x_2, y_2\}\)表示的替换使得\(x_1\)和\(y_2\)是满足最优解的条件,且替换\(\{x_1, y_1\}\)比替换\(\{x_2, y_2\}\)先进行。由于\(x_1\)是满足最优解的条件,而\(y_1\)不是,那么必有\(\frac {e} {n}\)(满足最优解的组装车间)\(< \frac {x_1+ y_1} {2}\)(二者之间线段的中点),这个结论是显然的(可以自己手玩)。同理有\(\frac {e} {n} > \frac {x_2 + y_2} {2}\),由此及上式得\(x_1 + y_1 > x_2 + y_2\),但我们已经事先排序保证\(x_1 + y_1 < x_2 + y_2\),矛盾。
实现起来就非常简单了,每次替换维护\(o\)和\(e\)的变化量,再用\(o - \frac {e ^ 2} {n}\)和\(e / n\)更新最小值和答案就行了。
#include <cstdio>
#include <cctype>
#include <vector>
#include <algorithm>
#define R register
#define I inline
#define B 1000000
#define D double
#define P pair <int, int>
using namespace std;
const int N = 10003;
char buf[B], *p1, *p2;
I char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, B, stdin),p1 == p2) ? EOF : *p1++; }
I int rd() {
R int f = 0, b = 1;
R char c = gc();
while ((c < 48 || c > 57) && c ^ 45)
c = gc();
if (c == 45)
b = 0, c = gc();
while (c > 47 && c < 58)
f = f * 10 +(c ^ 48), c = gc();
return b ? f : ~f + 1;
}
vector <int> f[N];
vector <pair <int, int> > g;
I D pow(D x) { return x * x; }
I int cmp(P x, P y) { return x.first + x.second < y.first + y.second; }
int main() {
R int n = rd(), m = rd(), i, j, s, x, y;
D o = 0, e = 0, del, tmp, ans;
for (i = 1; i <= m; ++i)
x = rd(), y = rd(), f[y].push_back(x);
for (i = 1; i <= n; ++i) {
s = f[i].size(), sort(&f[i][0], &f[i][0] + s);
for (j = 1; j < s; ++j)
g.push_back(make_pair(f[i][j - 1], f[i][j]));
}
for (i = 1; i <= n; ++i)
o += pow(f[i][0]), e += f[i][0];
tmp = o - pow(e) / n, ans = e / n, s = g.size(), sort(&g[0], &g[0] + s, cmp);
for (i = 0; i < s; ++i) {
o += pow(g[i].second) - pow(g[i].first), e += g[i].second - g[i].first;
if ((del = o - pow(e) / n) < tmp)
tmp = del, ans = e / n;
}
printf("%.4lf", ans);
return 0;
}
[CQOI2012]组装 贪心的更多相关文章
- 【BZOJ2666】[cqoi2012]组装 贪心
[BZOJ2666][cqoi2012]组装 Description 数轴上有m个生产车间可以生产零件.一共有n种零件,编号为1~n.第i个车间的坐标为xi,生产第pi种零件(1<=pi< ...
- Luogu3162 CQOI2012 组装 贪心
传送门 如果提供每一种零件的生产车间固定了,那么总时间\(t\)与组装车间的位置\(x\)的关系就是 \(t = \sum (x-a_i)^2 = nx^2-2\sum a_ix + \sum a_i ...
- [CQOI2012]组装 (贪心)
CQOI2012]组装 solution: 蒟蒻表示并不会模拟退火,所以用了差分数组加贪心吗.我们先来看题: 在数轴上的某个位置修建一个组装车间 到组装车间距离的平方的最小值. 1<=n< ...
- luogu P3162 [CQOI2012]组装
传送门 mdzz,为什么这题有个贪心的标签啊qwq 首先考虑每一种车间,对于每相邻两个车间,在中点左边那么左边那个会贡献答案,在右边就右边那个更优 所以总共会有m-1个这样的分界中点,然后最多有m+1 ...
- BZOJ 2666: [cqoi2012]组装
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2666 题意:n种零件,m个位置,每个位置有一种零件.求一个位置x,使得cost(1 ...
- P3162 [CQOI2012]组装
传送门 退火大法好 我并不会正解于是只好打退火了--其他没啥好讲--只要对每一种颜色开一个vector,存一下所有这个颜色的位置,判定的时候可以去所有的颜色里二分找到前缀和后缀,把和当前点距离小的加入 ...
- 【题解】P3162CQOI2012组装
[题解][CQOI2012]组装 考虑化为代数的形式,序列\(\left[a_i \right]\)表示选取的\(i\)种类仓库的坐标. \(ans=\Sigma(a_i-x)^2,(*)\),展开: ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- [BZOJ2667][cqoi2012]模拟工厂 贪心
2667: [cqoi2012]模拟工厂 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 367 Solved: 184[Submit][Status] ...
随机推荐
- python 基础-----数字,字符串,if while 循环 数据类型的转换简单介绍
一.第一个python小程序 首先我们要知道python创立的初衷是:Python崇尚优美.清晰.简单. 所以python比起其他的语言需要的工作量少了一半都不止,比如和现在一直霸占语言排行榜 榜首 ...
- [翻译] PPiAwesomeButton
PPiAwesomeButton https://github.com/pepibumur/PPiAwesomeButton UIButton category with new methods to ...
- [原创]获取JS数组最大值、最小值
核心关键 JS有Array数组对象,使用prototype内置属性扩展,增加Array数组max().min()方法 具体代码 //最小值 Array.prototype.min = function ...
- 铁乐学Python_day08_文件操作
一.[基本的文件操作] 参数: 1.文件路径: 2.编码方式: 3.执行动作:(打开方式)只读,只写,追加,读写,写读! #1. 打开文件,得到文件句柄并赋值给一个变量 f = open('E:/Py ...
- JDBC 连接mysql获取中文时的乱码问题
前段时间学习JDBC,要连接mysql获取数据.按照老师的样例数据,要存一些名字之类的信息,用的都是英文名,我当时就不太想用英文,就把我室友的名字存了进去,嘿嘿,结果,出问题了. 连接数据库语句: s ...
- Data Compression
数据压缩 introduction 压缩数据可以节省存储数据需要的空间和传输数据需要的时间,虽然摩尔定律说集成芯片上的晶体管每 18-24 个月翻一倍,帕金森定律说数据会自己拓展来填满可用空间,但数据 ...
- 第2次作业——APP案例分析
第一部分 调研, 评测 1.下载软件并使用起来,描述最简单直观的个人第一次上手体验. 知乎,中文互联网最大的知识平台.使用知乎这个APP3年了,目睹了它的兴盛(当然没有衰亡@_@).打开这款APP,主 ...
- quartz(转)
1. CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 ...
- PostgreSQL学习----命令或问题小结
PostgreSQL学习--命令或问题小结 小序 接触PostgreSQL也有好长时间了,知识不总结梳理,似乎总不是自己的,继续努力吧少年!以此记录我的软件工艺之路! 1,查看模式搜索路径 SHOW ...
- Alpha冲刺(5/10)——追光的人
1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...