zoukankan      html  css  js  c++  java
  • P4799 [CEOI2015 Day2]世界冰球锦标赛

    题目大意:有$n$个数,求任意选出若干个数,使其和不大于$m$的方案数。

    暴力:每个数只有两种情况:选或者不选,然后再二进制判断计数。

    优化:

    将其分成两个集合$A$和$B$,其中$|A| = |B| = dfrac{n}{2}$

    $A$处理前$n$个数的方案个数并保留总和,$B$同理。

    然后``two-pointers``。

    时间复杂度大概是$Oleft(2 ^ {frac{n}{2}} ight)$,$n le 40$可以过。
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 long long m;
     5 long long a[100];
     6 long long A[1 << 20 + 2], B[1 << 20 + 2];
     7 int Acnt = 0, Bcnt = 0;
     8 long long ans = 0;
     9 
    10 inline long long read(void)
    11 {
    12     long long s = 0;
    13     int w = 1;
    14     char ch = getchar();
    15     while (!isdigit(ch))
    16     {
    17         if (ch == '-')
    18             w = -1;
    19         ch = getchar();
    20     }
    21     while (isdigit(ch))
    22     {
    23         s = s * 10 + ch - '0';
    24         ch = getchar();
    25     }
    26     return s * w;
    27 }
    28 
    29 void dfs(int now, int nn, long long sum)
    30 {
    31     if (sum > m)
    32         return;
    33     if (now > nn)
    34     {
    35         if (nn == n)
    36             A[++Acnt] = sum;
    37         else
    38             B[++Bcnt] = sum;
    39         return;
    40     }
    41     dfs(now + 1, nn, sum);
    42     dfs(now + 1, nn, sum + a[now]);
    43     return;
    44 }
    45 
    46 int qfind(int R, int L)
    47 {
    48     int l = 0, r = L;
    49     int ans = 0;
    50     while (l <= r)
    51     {
    52         int mid = (l + r) >> 1;
    53         if (A[mid] + B[R] <= m)
    54         {
    55             ans = mid;
    56             l = mid + 1;
    57         }
    58         else
    59             r = mid - 1;
    60     }
    61     return ans;
    62 }
    63 
    64 int main(void)
    65 {
    66     n = read(), m = read();
    67     for (int i = 1; i <= n; i++)
    68     {
    69         a[i] = read();
    70     }
    71     dfs(1, n / 2, 0);
    72     dfs(n / 2 + 1, n, 0);
    73     sort(A + 1, A + Acnt + 1);
    74     sort(B + 1, B + Bcnt + 1);
    75     int l = Acnt, r = 1;
    76 
    77     while (l >= 1 && r <= Bcnt)
    78     {
    79         l = qfind(r, l);
    80         ans += l;
    81         r++;
    82     }
    83     printf("%lld
    ", ans);
    84     return 0;
    85 }
  • 相关阅读:
    软件质量的“奥秘”(一)——虚伪的质量
    IT项目管理中的假设约束依赖和承诺
    [转载]IT知识体系结构图
    如何看待项目开发过程中基于度量结果的绩效考评
    我常用的一些ASP自定义函数
    女生永远也不知道男生为什么***
    系统分析员、系统架构师、项目经理的区别
    软件工程知识体系全景图
    my music / NightWish / Groove Coverage / DJ
    qiushibaike.com
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/P4799.html
Copyright © 2011-2022 走看看