CF798D Mike and distribution

洛谷评测传送门

题目描述

Mike has always been thinking about the harshness of social inequality. He's so obsessed with it that sometimes it even affects him while solving problems. At the moment, Mike has two sequences of positive integers A=[a_{1},a_{2},...,a_{n}]A=[a1,a2,...,a**n] and B=[b_{1},b_{2},...,b_{n}]B=[b1,b2,...,b**n] of length nn each which he uses to ask people some quite peculiar questions.

To test you on how good are you at spotting inequality in life, he wants you to find an "unfair" subset of the original sequence. To be more precise, he wants you to select kk numbers P=[p_{1},p_{2},...,p_{k}]P=[p1,p2,...,p**k] such that 1<=p_{i}<=n1<=p**i<=n for 1<=i<=k1<=i<=k and elements in PP are distinct. Sequence PP will represent indices of elements that you'll select from both sequences. He calls such a subset PP "unfair" if and only if the following conditions are satisfied: 2·(a_{p1}+...+a_{pk})2⋅(a**p1+...+apk) is greater than the sum of all elements from sequence AA , and 2·(b_{p1}+...+b_{pk})2⋅(b**p1+...+bpk) is greater than the sum of all elements from the sequence BB . Also, kk should be smaller or equal to because it will be to easy to find sequence PP if he allowed you to select too many elements!

Mike guarantees you that a solution will always exist given the conditions described above, so please help him satisfy his curiosity!

输入格式

The first line contains integer nn ( 1<=n<=10^{5}1<=n<=105 ) — the number of elements in the sequences.

On the second line there are nn space-separated integers a_{1},...,a_{n}a1,...,a**n ( 1<=a_{i}<=10^{9}1<=a**i<=109 ) — elements of sequence AA .

On the third line there are also nn space-separated integers b_{1},...,b_{n}b1,...,b**n ( 1<=b_{i}<=10^{9}1<=b**i<=109 ) — elements of sequence BB .

输出格式

On the first line output an integer kk which represents the size of the found subset. kk should be less or equal to .

On the next line print kk integers p_{1},p_{2},...,p_{k}p1,p2,...,p**k ( 1<=p_{i}<=n1<=p**i<=n ) — the elements of sequence PP . You can print the numbers in any order you want. Elements in sequence PP should be distinct.

题意翻译

题意:给两个长度为n的数列A,B,要求至多选择n/2+1个下标,使得A数组中选出的数的和的两倍大于sumA,B数组中选出的数的和的两倍大于sumB

输入输出样例

输入 #1复制

输出 #1复制

题解:

2019.10.22模拟赛40分场

一看就是道贪心的题。这自然不必说。重点在于如何建立贪心策略和维护贪心的正确性(也是把本蒟蒻卡的死死的点)。

先来理解一下题意:要选出\(n/2+1\)对数,使得这些数的二倍比原数列和还大。

于是我们得到了一个结论:这些数是按对选的,也就是绑定选择。

根据这个思路,我们想到了构建结构体解决问题。

因为我们输出的时候要输出数组下标,所以我们不仅维护每个位置的数(a和b),而且还要构建一个映射关系,即要把数对的位置也存进结构体。这些都是基础操作,我就不多说了。

考场上直接写了爆搜加部分分骗了40

后来看了正解,加上一些自己的理解和证明,得出了这篇辣鸡博客。

我曾经\(YY\)过,贪心总是和排序结合在一起的,这道题当然不会例外。但是我们这道题的排序有一些困难,难点还是在于绑定选择。我们能通过对\(A\)数列或\(B\)数列排序来维护有解的情况,但是我们并无法构建一种可行的排序,使得在维护\(A\)序列的同时还维护\(B\)序列的正确性。

于是我们“退而求其次”,我们只维护\(A\)序列,然后乱搞搞尽量维护\(B\)序列的正确性,能行就行,不行拉倒。

然后我们建一个结构体\(num[i].a.b.id\),分别存\(A,B\)序列的值以及序号。之后按照\(A\)序列进行排序,根据贪心原则,我们选靠前的项一定对答案贡献更大。那我们就直接考虑\(B\)序列。

这里的贪心策略与正常的贪心略有不同。对于这种题目,我们经常会被拐进:对于每个物品,选还是不选的误区。于是我们便走进了一个死胡同,发现好像怎么证明都无法得出正确的答案。所以,我们提出一种全新的贪心选择的思路(应该也比较常见):对于一对物品,选第一个还是第二个。

于是,我们先选\(num[1]\)(因为个数是\(n/2+1\)),然后对于之后的每对物品,选择其中\(num[i].b\)值更大的那个。这就是正确的贪心决策了。

怎么证明呢?

因为我们是按\(A\)关键词排序,所以得出的序列肯定是\(A\)大的在前面,因为我们是捆绑选择。所以我们在\(A\)序列有序的基础上按对选择\(B\),得出的答案一定是最优的。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e5+1;
int n,tot,ans[maxn];
struct node
{
int a,b,id;
}num[maxn];
bool cmp(node a,node b)
{
return a.a>b.a;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i].a);
num[i].id=i;
}
for(int i=1;i<=n;i++)
scanf("%d",&num[i].b);
sort(num+1,num+n+1,cmp);
int cnt=n/2+1;
ans[++tot]=num[1].id;
for(int i=2;i<=n;i+=2)
{
if(num[i].b>num[i+1].b)
ans[++tot]=num[i].id;
else
ans[++tot]=num[i+1].id;
}
printf("%d\n",cnt);
for(int i=1;i<=cnt;i++)
printf("%d ",ans[i]);
return 0;
}

CF798D Mike and distribution的更多相关文章

  1. CF798D Mike and distribution 贪心

    我感觉这道题挺神的~ 假设 $a[i]=b[i]$,那么我们可以将 $a$ 降序排序,然后你发现只要你按照 $1,3,5......n$ 这么取一定是合法的. 而我们发现 $2$ 比取 $3$ 优,取 ...

  2. codeforces 798 D. Mike and distribution

    D. Mike and distribution time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  3. #410div2D. Mike and distribution

    D. Mike and distribution time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  4. D. Mike and distribution 首先学习了一个玄学的东西

    http://codeforces.com/contest/798/problem/D D. Mike and distribution time limit per test 2 seconds m ...

  5. Codeforces 798D Mike and distribution(贪心或随机化)

    题目链接 Mike and distribution 题目意思很简单,给出$a_{i}$和$b_{i}$,我们需要在这$n$个数中挑选最多$n/2+1$个,使得挑选出来的 $p_{1}$,$p_{2} ...

  6. CF410div2 D. Mike and distribution

    /* CF410div2 D. Mike and distribution http://codeforces.com/contest/798/problem/D 构造 题意:给出两个数列a,b,求选 ...

  7. [CF798D]Mike and distribution_贪心

    Mike and distribution 题目链接:http://codeforces.com/problemset/problem/798/D 数据范围:略. 题解: 太难了吧这个题..... 这 ...

  8. Codeforces 798D Mike and distribution - 贪心

    Mike has always been thinking about the harshness of social inequality. He's so obsessed with it tha ...

  9. 【算法系列学习】codeforces D. Mike and distribution 二维贪心

    http://codeforces.com/contest/798/problem/D http://blog.csdn.net/yasola/article/details/70477816 对于二 ...

随机推荐

  1. Redux使用

    思想 应用中所有的state都以一个对象树的形式储存在一个单一的store中.唯一能改变state的办法是触发action,一个描述发生什么的对象.为了描述action如何改变state树,需要编写r ...

  2. 设计模式-State(行为模式)-很好的实现了对象的状态逻辑与动作实现的分类,状态逻辑在State的派生类实现,动作可以放在Context类中实现。

    以下代码来源: 设计模式精解-GoF 23种设计模式解析附C++实现源码 //Context.h #pragma once class State; class Context { public: C ...

  3. Note | 常用指令,工具,教程和经验笔记

    目录 图像处理 机器学习和数学 编程环境和工具 写作工具 其他 图像处理 获取图像频域并分解为高低频:https://www.cnblogs.com/RyanXing/p/11630493.html ...

  4. 【C#】C#中的HtmlEncode与HtmlDecode:HttpUtility.HtmlEncode,HttpUtility.HtmlDecode,Server.HtmlEncode,Server.HtmlDecode,WebUtility.HtmlEncode,WebUtility.HtmlDecode

    HtmlEncode(String) 将字符串转换为 HTML 编码字符串. HtmlDecode(String) 将已经为 HTTP 传输进行过 HTML 编码的字符串转换为已解码的字符串. 在we ...

  5. 【STM32H7教程】第30章 STM32H7的USART应用之八个串口FIFO实现

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第30章       STM32H7的USART应用之八个串口 ...

  6. gitlab与jenkins结合构建持续集成

    Jenkins是java编写,需要安装JDK,这里采用 yum 安装,对版本有需求的,可以到 oracle 官网下载 JDK. yum install -y java-1.8.0-openjdk 一. ...

  7. 数据库——SQL-SERVER练习(1)连接与子查询

    一.实验准备 1.复制实验要求文件及“CREATE-TABLES.SQL”文件, 粘贴到本地机桌面. 2.启动SQL-SERVER服务. 3. 运行查询分析器, 点击菜单<文件>/< ...

  8. Requests库主要方法解析以及Requests库入门需要掌握的框架

    Requests库主要方法解析以及Requests库入门 1.requests.request(method,url,**kwargs) **kwargs:控制访问的参数,均为可选项 params:字 ...

  9. 动态SQL屏幕条件选择(里面还有赋值的新语法)

    有时候屏幕条件中使用PARAMETERS时候,如果你为空的话,会查不出数据,但是可能你的想法是不想限制而已,但是系统默认理解为了空值,这个时候,如果取判断一下条件是不是空,在SQL里决定写不写的话,会 ...

  10. for与foreach区别

    首先说一下for循环: 格式:for( ; ; ){}; public static void main(String[] args) { List<String> arr = new A ...