题面:

传送门

题目描述:

灭霸想要摧毁复仇者联盟的基地。基地的长度为2的n次方,基地可以看成是一个长度为2的n次方的数组。基地的每一个位置可以由很多个超级英雄,但是一个超级英雄只能站一个位置。灭霸想用最小的力量摧毁复仇者联盟的基地。从破坏一整个基地开始,每一步他可以执行其中一项操作:
1.如果当前基地长度大于等于2,那么灭霸可以把基地分开成两半。
2.烧掉当前基地。如果当前基地没有任何超级英雄,则需要A的力量。否则,灭霸需要B*num*l的力量。其中num是当前基地的超级英雄数量,l是当前基地的长度。
问:灭霸所需要的最小力量是多少?
 

题目分析:

这道题先要读懂题意:对于每次操作,可以选择直接破坏(燃烧)当前基地,或者把基地分成两半再进行破坏。
1.题意理解:
刚开始,基地是连成一体的:
灭霸可以直接把整个基地破坏,其中需要用B*3*8的力量,这时,整个基地就被破坏完了。
但是,我们也可以这样:不把整个基地直接破坏,先分成两半:
再分别破坏两个基地。或者,继续分成两半(这时有三种方案):
再分别破坏它们。或者,再分成两半......
这里要注意的是:如果一个基地一个英雄都没有,就直接用A的力量破坏掉,而不是尝试分半后再继续破坏。
 
2.很容易发现,其实这个就类似于归并排序(递归?dfs?分治?二分???)的做法就可以完成这道题了。在找某个区间有多少个超级英雄时要用二分去找,不然会超时。
 
3.我们可以写一个dfs的函数,传入1和2^n(也就是传入区间[1, 2^n])。然后,我们在dfs函数里面尝试对这个区间分半和不分半的操作:如果不分半,就直接计算结果:计算当前区间里面有多少个英雄。如果没有英雄,dfs函数就直接返回这个区间要A的力量。如果有英雄,就用二分的方法(先要把英雄站的位置排好序)或者用upper_bound,lower_bound,算出当前区间的英雄个数,然后算出要花费的力量,再计算这个区间如果分半后(用递归分半)的需要花费的力量(大小就是dfs(l, mid)+dfs(mid+1, r),其中mid = (l+r)/2 ),取两者的最小值,然后再返回就行了。
 
4.坑:二分容易弄错,数据没有开long long.
 
 
AC代码:
 1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <cmath>
5 #include <algorithm>
6 using namespace std;
7 const int maxn = 1e5+5;
8 long long n, k, A, B;
9 long long a[maxn];
10
11 long long binary(long long x){ //二分,左开右闭的设置
12 long long l = 0, r = k+1;
13 long long mid;
14 while(l < r){
15 mid = (l+r)/2; //左开右闭向下取整
16 if(a[mid] < x) l = mid+1;
17 else r = mid;
18 }
19 return l;
20 }
21
22 long long dfs(long long l, long long r){
23 int num = binary(r+1)-binary(l); //计算出位置区间[l, r]内的英雄个数
24
25 long long res;
26 if(!num) return A;
27 else res = B*num*(r-l+1);
28
29 if(l == r) return res; //递归终点
30 else return min(res, dfs(l, (l+r)/2)+dfs((l+r)/2+1, r)); //取小的作为结果
31 }
32
33 int main(){
34 cin >> n >> k >> A >> B;
35 for(int i = 1; i <= k; i++){
36 scanf("%lld", &a[i]);
37 }
38 sort(a+1, a+k+1);
39
40 //为了方便用二分而设置的
41 a[k+1] = 2e9;
42
43 long long r = (1<<n);
44
45 cout << dfs(1, r) << endl;
46 return 0;
47 }
 
 
 

最新文章

  1. css随笔1
  2. 点击页面其它地方隐藏div所想到的jQuery的delegate
  3. mysql多表查询例子
  4. 反转字符串--C和Python
  5. sql分类及基本sql操作,校对规则(mysql学习笔记二)
  6. ADO与ADO.NET的区别与介绍
  7. Differential Geometry之第三章曲面的局部理论
  8. nginx面试题
  9. 如何将angularJs项目与requireJs集成
  10. 让自己的C++程序(非服务程序)运行为一个windows service
  11. CPU内存管理和linux内存分页机制
  12. HDU 5800 To My Girlfriend
  13. AOP:代理实现方式①通过继承②通过接口
  14. 【JVM虚拟机】(9)-- JVM是如何处理异常的
  15. Android 7.0及以上使用OpenCL
  16. jQuery 字符串拼接
  17. PAT-GPLT训练集 L1-039 古风排版
  18. MySQL 两个死锁样例
  19. python selenium-7自动发送邮件
  20. R语言数据结构一

热门文章

  1. pillow KeyError: &#39;WEBP&#39;
  2. 电影推荐系统---协同过滤算法(SVD,NMF)
  3. 牛客多校第九场H Cutting Bamboos(主席树 区间比k小的个数)题解
  4. Redis 集合统计(HyperLogLog)
  5. js &amp; document.execCommand
  6. Protocol Buffers All In One
  7. html fragment &amp; svg remove xml namespace
  8. java数据类型(基础篇)
  9. ⑧SpringCloud 实战:引入 Actuator监控+整合监控页面
  10. go语言第一天(变量与基本类型)