可爱の星空 (递推)

可爱の星空

链接:https://ac.nowcoder.com/acm/problem/20650

题目描述
“当你看向她时,有细碎星辰落入你的眼睛,真好。”——小可爱
在一个繁星闪烁的夜晚,卿念和清宇一起躺在郊外的草地上,仰望星空。
星语心愿,他们,想把这片星空的星星,连成一棵漂亮的树,将这美好的景色记录下来。
现在,天上共有n颗星星,编号分别为1,2…n,一开始任何两个点之间都没有边连接。
之后,他们两个想在在(u,v)之间连无向边,需要付出|u联通块大小-v联通块大小|的代价。
他们两个想用最少的代价来使这n个点联通,所以他们想知道最小代价是多少。
(多组数据
输入描述:
第一行一个正整数,表示数据组数T

接下来T行每行一个正整数,表示询问的n
输出描述:
T行,每行一个数表示答案
示例1
输入

1
5

输出

2

说明
1,2…5五个点,连边顺序为(1,2),(3,4),(1,5),(5,3),代价为0,0,1,1,总代价为2,是n=5的时候最优答案。

虽然(1,2),(2,3),(3,4),(4,5)也可以,但是代价为0,1,2,3,总代价为6,比2大。
备注:
对于20%的数据,T<=2,n<=10

对于40%的数据,T<=10,n<=1000

对于60%的数据,T<=100000,n<=100000

对于另外40%的数据,T=1,n<=1000000000000

题意 :
样例解析,连通块的代价指的是两个连通块个数之差的绝对值
列如单点1和2连接的话代价就是1 - 1 = 0; 3 和 4同理
1 和 5的时候发生改变 1已经和2连接了,所以和5连接的时候代价就是 2 - 1 = 1;
5 和 3此时就是两个大的连通块相减就是 3 - 2 = 1;

题解 :
知道了代价之后,很清楚的是单点之间先连接然后逐个增加;
含义 : n = 5时可以分成n = 2 和 n = 3;n = 6可以分成n = 3 和n = 3;

#include <iostream>
using namespace std;
typedef long long ll;
ll n;

ll solve(ll n){
    if(n == 1 || n == 2) return 0;
    if(n & 1) return solve(n/2) + solve(n/2+1) + 1;
    else return solve(n / 2) * 2;
}
int main(){
    int t;cin >> t;
    while(t --){
        cin >> n;
        cout <<solve(n) << endl;
    }
    return 0;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值