前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CodeCraft-19 and Codeforces Round #537 (Div. 2) C. Creative Snap(二分+分治)

CodeCraft-19 and Codeforces Round #537 (Div. 2) C. Creative Snap(二分+分治)

作者头像
Ch_Zaqdt
发布2019-03-04 15:31:56
4060
发布2019-03-04 15:31:56
举报
文章被收录于专栏:Zaqdt_ACMZaqdt_ACM

题目链接:https://codeforces.com/contest/1111/problem/C

       题意是输入n,k,a,b,表示有一个长度为2^n的区间,然后输入k个数,表示有k个超级英雄,然后输入k个超级英雄所在的位置,灭霸有两种操作,一种是删掉一个区间,如果这个区间里没有超级英雄代价就是a,如果有超级英雄代价就是这个区间长度*超级英雄个数*b,另一种操作就是将这个区间等分为[l, mid]和[mid + 1, r],问灭霸消灭所有超级英雄的最小代价是多少。

       大致思路就是按题意去模拟,用分治的思想来实现区间的等分,从而更新最小值,问题是如何判断区间内有多少个超级英雄,这里可以用二分去查找,查找区间内超级英雄的个数就是upper_bound(pre, pre + m, r) - lower_bound(pre, pre + m, l),这个长度就是区间内超级英雄的个数。


AC代码:

代码语言:javascript
复制
#include <bits/stdc++.h>
#define ll long long
#define maxn 100005
using namespace std;
int n, m, a, b;
int pre[maxn];

ll dfs(int l,int r){
  int xx = upper_bound(pre, pre + m, r) - lower_bound(pre, pre + m, l);
  if(xx == 0) return a;
  ll ans = (r - l + 1LL) * xx * b;
  int mid = (l + r) >> 1;
  if(l != r)
  ans = min(ans, dfs(l, mid) + dfs(mid + 1, r));
  return ans;
}

int main()
{
  scanf("%d%d%d%d",&n,&m,&a,&b);
  for(int i=0;i<m;i++){
    scanf("%d", &pre[i]);
  }
  sort(pre, pre + m);
  ll ans = dfs(1, 1 << n);
  printf("%lld\n", ans);
  return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年02月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档