博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Round #410 (Div. 2) D. Mike and distribution 思维+数学
阅读量:5317 次
发布时间:2019-06-14

本文共 2113 字,大约阅读时间需要 7 分钟。

链接:

题意:

给你两个长度为n的数列a和b,让你选n/2+1个下标,使得2*∑ai>suma,2*∑bi>sumb

题解1:

用一个叫random_shuffle的东西,每次都乱选,然后暴力前n/2+1个。

这种做法真的是毫无人性啊。以后不会的就这么办吧

代码:

31 ll a[MAXN], b[MAXN], c[MAXN];32 33 int main() {34     ios::sync_with_stdio(false);35     int n;36     cin >> n;37     rep(i, 0, n) c[i] = i;38     ll suma = 0, sumb = 0;39     rep(i, 0, n) cin >> a[i], suma += a[i];40     rep(i, 0, n) cin >> b[i], sumb += b[i];41     while (1) {42         random_shuffle(c, c + n);43         ll A = 0, B = 0;44         rep(i, 0, n / 2 + 1) A += a[c[i]], B += b[c[i]];45         if (2 * A > suma && 2 * B > sumb) break;46     }    47     cout << n / 2 + 1 << endl;48     rep(i, 0, n / 2 + 1) cout << c[i] + 1 << ' ';49     return 0;50 }

 

题解2:

首先注意到,选出n / 2 + 1个数,2倍的和大于总和,等价于选出n / 2 + 1个数,总和大于剩下的数。

因为可以取n / 2 + 1个,那么先对A排序,B不动,先把A[1]选了(这个是用在证明A数组成立用的),A【1】是当前A中最大的了。当然了也选了一个B,就是选了B[A[1].id],

然后每两个做一pair,选一个比较大的B,也就是max(B[A[i].id], B[A[i + 1].id])

这样,B数组是满足的,这很容易证明,因为没一对中,都选了一个较大的。然后加上第一个,总和肯定大于剩下 的。

也就是

max(b[1], b[2]) >= min(b[1], b[2])

max(b[3], b[4]) >= min(b[3], b[4])

max(b[5], b[6]) >= min(b[5], b[6])

那么全部相加,不等号方向不变。而且开头还有一个b[A[1].id]加了进来,所以是严格大于的。

 

再来看看A的证明。

第一是选了a[1]

然后选a[2]和a[3]的那个呢?不固定的,还要看B,但是不管,有以下不等式。

a[1] >= any(a[2], a[3])

any(a[2], a[3]) >= any(a[4], a[5])

any(a[4], a[5]) >= any(a[5], a[6])

也就是,你选了一个a[1],然后a[2]和a[3]选那个是没关系的,可以用a[1]和它比较,然后又因为选了any(a[2], a[3]),那么你a[4]和a[5]选那个是没所谓的,因为可以用any(a[2], a[3])和它比较。

最后,any(a[n - 1], a[n]) > 0,所以是严格大于的。

代码:

31 struct Node {32     int id, a, b;33     bool operator <(const Node &t) const {34         return a > t.a;35     }36 }p[MAXN];37 38 int main() {39     ios::sync_with_stdio(false);40     int n;41     cin >> n;42     VI ans;43     rep(i, 0, n) p[i].id = i;44     rep(i, 0, n) cin >> p[i].a;45     rep(i, 0, n) cin >> p[i].b;46     sort(p, p + n);47     ans.pb(p[0].id);48     for (int i = 1; i < n; i += 2) {49         int t = p[i].id;50         if (p[i].b < p[i + 1].b) t = p[i + 1].id;51         ans.pb(t);52     }53     cout << ans.size() << endl;54     rep(i, 0, ans.size()) cout << ans[i] + 1 << ' ';55     return 0;56 }

 

转载于:https://www.cnblogs.com/baocong/p/6783227.html

你可能感兴趣的文章
顺序存储结构和链式存储结构
查看>>
ANDROID布局实现圆角边框
查看>>
广告banner:手动滑动切换,自动切换,点击跳转,异步加载网络图片
查看>>
环境变量
查看>>
Entity Framework安装方法
查看>>
网络对抗技术作业1
查看>>
JavaScript笔记
查看>>
10个给力的在线Web设计开发工具介绍
查看>>
【作品】多人贪吃蛇
查看>>
CSS进阶(二十三)用户界面样式
查看>>
飞鸽传书 绑定指定网卡
查看>>
XNA系列(1)
查看>>
注册表清理bat
查看>>
《和时间做朋友》读后感
查看>>
分布式系统中的必备良药 —— 服务治理
查看>>
小坑过河
查看>>
日期控件应用
查看>>
编写一个函数char_contains(char str[],char c), 如果字符串str中包含字符c则返回数值1,否则返回数值0...
查看>>
LinkBinTree
查看>>
js 事件委托 事件代理
查看>>