一道题

Posted HWIM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道题相关的知识,希望对你有一定的参考价值。

题目

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

输入格式

第一行一个整数 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 函数最值

以上是关于一道题的主要内容,如果未能解决你的问题,请参考以下文章

一道面试题:静态代码块的执行顺序

每天一道Java题[11]

PHP代码审计-小题一道

一道有趣的签到题

每天一道Java题[9]

记一道面试题:手写一个内存泄漏的代码,如何修正