• 函数最值(位运算)


    函数最值

    题目

    给定一个n 个数的数组A,函数F(x) = a[i] * x的第i 个二进制位。求F的最大值,x为整数且0<=x<=m.

    输入格式

    第一行一个整数 n 表示数组大小
    第二行 n 个整数表示 Ai,Ai 有正有负
    接下来一个数 m 的二进制表示,从前到后分别是低位到高位

    输出格式

    F(X)的最大值

    样例

    输入:
    4
    -1 1 2 0
    0010
    输出:
    2
    样例解释:
    n = 4
    f(0) = 0 
    f(1) = -1; (1 = 1 = 1*a[1])
    f(2) = 1 (2 = 01(倒序) = 0*a[1]+1*a[2])
    f(3) = 0 
    f(4) =2 

    数据范围:

    30% n<=20

    100% n<=100000

    题解

    题目要求将x拆成二进制后,每个位置是1的,加上对应的a数组中的数。

    那么对于30%的数据可以直接枚举,100%的数据显然不可以。

    然后会发现这样一个性质:如果每个位置都没有约束,也就是可以随便取了,这时可以O(n)的时间算出答案。

    之后我们只要创造没有限制的情况就可以了。

    比如对于11001000(正过来了,倒着不舒服)

    首先只考虑后三位,如果最后一个1是0的话,这三位随便取了,O(n)算出答案,注意这个答案需要加上最后一个1前面的的所有价值,不包括最后一个1

    之后找到第二个1,同理让它成为0,算出答案,

    这样其实就是分层处理的,

    首先的所有1的价值11001000

    之后是 11000000~11000111

    10000000~10111111

    0~1111111

    惊奇的发现每个0~11001000的数全都包含了!

    代码实现:像上面一样从后往前扫一遍。

    注意:一定要开long long,题面居然没写a的范围!!!

    开long long与不开的区别是70分!!!

    code

     1 /*
     2 开Long Long与不开long long 的区别是70分!!!
     3 */
     4 
     5 #include<cstdio>
     6 #include<algorithm>
     7 #include<cstring>
     8 
     9 using namespace std;
    10 
    11 const int MAXN = 200100;
    12 
    13 long long a[MAXN];
    14 long long m[MAXN];
    15 long long sum = 0,mx = 0,ans,n;//mx谁都不选是0 
    16 char s[MAXN];
    17 
    18 inline long long read() {
    19     long long x = 0,f = 1;char ch = getchar();
    20     for (; ch<'0'||ch>'9'; ch = getchar() )
    21         if (ch=='-') f = -1;
    22     for (; ch>='0'&&ch<='9'; ch = getchar())
    23         x = x*10+ch-'0';
    24     return x*f;
    25 }
    26 void work(int l,int r) {
    27     for (int i=l; i<=r; ++i) {
    28         if (a[i] > 0) mx += a[i];
    29     }
    30 }
    31 int main() {
    32     
    33 
    34     n = read();
    35     for (int i=1; i<=n; ++i) a[i] = read();
    36     scanf("%s",s);
    37     int len = strlen(s);
    38     for (int i=0; i<len; ++i) {
    39         if (s[i]=='1') {
    40             m[i+1] = 1;sum += a[i+1];
    41         }
    42         else m[i+1] = 0;        
    43     }
    44     ans = sum;
    45     long long tmp;int L = 1;
    46     for (int i=1; i<=n; ++i) {
    47         if (m[i]==1) {
    48             sum -= a[i];
    49             work(L,i-1);L = i;
    50             tmp = max(mx+sum,mx);
    51             ans = max(tmp,ans);
    52         }
    53     }
    54     printf("%lld",ans);    
    55     return 0;
    56 }

    清北刷题班 by ccl 函数最值

  • 相关阅读:
    HtmlAgilityPack
    随笔-20150513
    过滤掉html 标签
    json转换
    第28月第3天 c语言读写文件
    第27月第28天 iOS bundle
    第27月第27天 https
    第27月第25天 clang -rewrite-objc main.m
    第27月第24天 git pull fetch
    第27月第18天 epoll lt et
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7794993.html
Copyright © 2020-2023  润新知