NC50038 kotori和糖果

题目

题目描述

kotori共有 n 块糖果,每块糖果的初始状态是分散的,她想把这些糖果聚在一堆。但她每次只能把两堆糖果合并成一堆。

已知把两堆数量为 ab 的糖果聚在一堆的代价是 |ab|

kotori想知道,她把这 n 块糖果聚在一堆的最小代价是多少?

输入描述

第一行是一个正整数 T ,代表数据组数。

第二行到第 T+1 行,每行一个非负整数 n ,代表kotori的糖果总数量。

输出描述

每行一个整数,代表kotori需要花费的最小代价。

示例1

输入

2
5
6

输出

2
2

说明

n=5时,kotori可以这样聚集糖果:

1 1 1 1 1

2 1 1 1

2 2 1

2 3

5

每一步的代价分别是0,0,1,1,总代价为2。

备注

对于 50% 的数据,0<T100000,0n100000

对于另外 50% 的数据,T=1,0n1018

题解

知识点:贪心,分治。

显然,每次合并如果两堆糖果数量刚好是合并后总数一半的时候代价最小。

map 记忆化搜索,注意 n=0 的情况特判。

时间复杂度 O(n)

空间复杂度 O(n)

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
map <ll, ll> mp;
ll dg(ll n) {
if (n <= 1) return 0;
if (mp.count(n)) return mp[n];
if (n & 1) return mp[n] = dg(n >> 1) + dg((n >> 1) + 1) + 1;
else return mp[n] = dg(n >> 1) << 1;
}
bool solve() {
ll n;
cin >> n;
cout << dg(n) << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
posted @   空白菌  阅读(923)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示