zoukankan      html  css  js  c++  java
  • Codeforces Round #410 (Div. 2) D. Mike and distribution 思维+数学

    链接:

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

    题意:

    给你两个长度为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 }
  • 相关阅读:
    ceph集群jewel版本 rbd 块map 报错-故障排查
    基本的Ceph性能测试工具和方法
    dd命令的高级应用
    Ceph recover的速度控制
    Linux mount命令
    Centos7.2:搭建Ceph管理系统Inscope
    rpm --import /etc/pki/rpm-gpg/RPM* 有什么用?
    dd命令的解释
    Playbooks 中的错误处理
    Ansible之Playbooks的when语句
  • 原文地址:https://www.cnblogs.com/baocong/p/6783227.html
Copyright © 2011-2022 走看看