题意:有2的n次方个基地,每个基地有若干人,现在要毁灭所有基地,有a和b两个值。选择2个及以上基地时,可以将它们一切为二地分别毁灭,如果这里有人,要花费人*b*长度,如果没人,花费a。求毁灭所有基地的最小花费。
思路:排序人的位置后,可以二分得到当前基地l到r的人数,如果没人,这段就就花费a,如果有人就花费 人*b*长度,然后和将这块分开递归上来的花费做比较取min即可。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
const ll maxv = 1e5 + 5;
ll n, k, a, b, gi[maxv];
ll dfs(ll l, ll r)
{
ll sum = 0;
ll mid = (l + r) / 2;
ll num = upper_bound(gi + 1, gi + 1 + k, r) - lower_bound(gi + 1, gi + 1 + k, l);
if (!num)
{
sum = a;
}
else
{
sum = (b*num*(r - l + 1));
if (l + 1 <= r)
{
sum = min(sum, dfs(l, mid) + dfs(mid + 1, r));
}
}
return sum;
}
int main()
{
scanf("%lld %lld %lld %lld", &n, &k, &a, &b);
for (ll i = 1; i <= k; i++)
{
scanf("%lld", &gi[i]);
}
sort(gi + 1, gi + 1 + k);
ll ans = dfs(1, 1 << n);
printf("%lld\n", ans);
return 0;
}