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

http://codeforces.com/contest/798/problem/D

http://blog.csdn.net/yasola/article/details/70477816

对于二维的贪心我们可以先让它变成其中一维有序,这样只需要重点考虑另一维,就会简单很多。

首先,对于题目要求的选择元素之和两倍大与所有元素之和,我们可以转化为选择元素之和大于剩下的。然后我们可以将下标按照a从大到小排序。然后选择第一个,之后每两个一组,选择b大的一个,如果n是偶数再选择最后一个。

至于这样写的正确性:首先对于数组b,每一组选择的都是大的,而且还有多选的,所以一定比剩下的大。对于数组a,从第一个开始看,当前选择的,一定比下一组剩下的a大。所以这样贪心就一定正确。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7
 8 using namespace std;
 9 const int maxn=1e5+10;
10 struct node
11 {
12     int x;
13     int id;
14 }a[maxn],b[maxn];
15 int n;
16 bool cmp(const node& aa,const node& bb)
17 {
18     return aa.x>bb.x;
19 }
20 int main()
21 {
22     scanf("%d",&n);
23     for(int i=0;i<n;i++)
24     {
25         scanf("%d",&a[i].x);
26         a[i].id=i+1;
27     }
28     for(int i=0;i<n;i++)
29     {
30         scanf("%d",&b[i].x);
31         b[i].id=i+1;
32     }
33     printf("%d\n",n/2+1);
34     sort(a,a+n,cmp);
35     printf("%d",a[0].id);
36     for(int i=1;i<n;i+=2)
37     {
38         if(b[a[i].id-1].x>b[a[i+1].id-1].x)
39         {
40             printf(" %d",a[i].id);
41         }
42         else
43         {
44             printf(" %d",a[i+1].id);
45         }
46     }
47     printf("\n");
48     return 0;
49 }

时间: 2024-11-08 20:24:53

【算法系列学习】codeforces D. Mike and distribution 二维贪心的相关文章

Codeforces 798D 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 = [a1, a2, ..., an] and B = [b1, 

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

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

Codeforces Round #578 (Div. 2) 二维差分 可做模板

题意: 在n*n的矩阵中,你可以选择一个k*k的子矩阵,然后将这个子矩阵中的所有B全部变为W,问你怎么选择这个子矩阵使得最终的矩阵中某一行全是W或者某一列全是W的个数最多 题解:考虑每一行和每一列,对于特定的一行来说,要想让其全变为W,那么子矩阵的左上角端点是在一个范围中的,因此我们可以把范围中的每一个值加1 为了速度选择用二维差分来做,最终矩阵中的最大值就是答案 此题可以作为二维差分模板 #include<bits/stdc++.h> #define forn(i, n) for (int

Codeforces Round #625 Div1 C,二维偏序,排序+线段树

题目 题意: 有若干武器A,攻击力A1,费用A2, 有若干铠甲B,防御力B1,费用B2, 有若干怪兽M,攻击力M1,防御力M2,奖励M3 你可以选择一把武器,一个铠甲,打败所有攻击和防御都严格小的怪兽,问最大收益. 思路: 典型的二维偏序问题,把攻击和防御想象成二维的坐标轴,我们要找到的其实就是一个矩形里(0,0)~(x,y)里收益-这个矩形的花费的最大值.我们可以排序一维,另一维用线段树维护,枚举的时候往里面加怪兽就好. 代码: #include <bits/stdc++.h> using

Codeforces 242E. XOR on Segment (二维线段树 lazy操作 xor)

题目链接: http://codeforces.com/problemset/problem/242/E 题意: 给出一个序列,有两种操作,一种是计算l到r的和,另一种是让l到r的数全部和x做异或运算. 思路: from: http://blog.csdn.net/u013912596/article/details/39006317 很显然直接暴力是不可能的,又是两种操作,又想到了线段树..但是这并不简单,异或操作该怎么处理? 异或是一种位运算,如果x的第j位是1,那么说明l到r的每个数的第j

【2048小游戏】——原生js爬坑之遍历算法显示二维数组内容

引言:做2048小游戏会将横纵方向的数字内容,存储在一个二维数组中,要将这个二维数组中的内容显示在页面上,就一定要用遍历算法来实现了. 一.二维数组存储    首先考虑用二维数组存储所有行数,列数  →  var  RN=4,CN=4; 然后再定义一个变量data 来保存这个二维数组  →  var  data; 游戏的所有主要执行程序都保存在start()函数下 → 启动游戏 保存存有行数,列数的二维数组到data中    关键代码 ↓ function start(){ data=[]; /

你也可以手绘二维码(二)纠错码字算法:数论基础及伽罗瓦域GF(2^8)

摘要:本文讲解二维码纠错码字生成使用到的数学数论基础知识,伽罗瓦域(Galois Field)GF(2^8),这是手绘二维码填格子理论基础,不想深究可以直接跳过.同时数论基础也是Hash算法,RSA算法等密码学的入门基础. 二维码生成算法最为核心的就是编码规则和纠错码字的生成.本篇专门讲解纠错涉及到的伽罗瓦域(Galois Field).本文内容大部分是阅读<密码编码学与网络安全>后参考相关PPT编写,如有遗漏或不严谨地方请参考专业书籍. 数论基础 整除,因数,素数 设 a , b(b≠0)

C++实现离散余弦变换(参数为二维指针)

http://www.cnblogs.com/scut-linmaojiang/p/5013590.html 写在前面 到目前为止已经阅读了相当一部分的网格水印等方面的论文了,但是论文的实现进度还没有更上,这个月准备挑选一些较为经典的论文,将其中的算法实现.在实现论文的过程中,发现论文中有用到一些空域转频率域的算法.因此也就想到了实现一下离散余弦变换.虽然本文的代码和网上很多已有的代码很类似,思路都没有太多的差别,但是本文有一个比较重要的改进.具体的说,网上现有DCT算法输入的是一个固定的二维数

[计算机图形学 with OpenGL] Chapter8 习题8.12 NLN二维线段裁剪算法实现

Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的边的信息. 此方法只在二维空间裁剪时使用,C-S和L-B裁剪方法则可应用到三维空间. 算法步骤: 1 先使用C-S裁剪算法的区域码判断方法,去除一部分在裁剪区域外面的线段.显示在完全在裁剪区域内的线段.其他不能判断的情况,采用NLN算法进行裁剪. 2 p1和p2若有一点在区域内,必要时交换端点以确保