每天一道 CodeForces 构造/思维题 难度1500 (day3)

简介: 每天一道 CodeForces 构造/思维题 难度1500 (day3)

1题目

题目链接 Factorials and Powers of Two

题目大意:

给你一个整数n(1<=n<=1e12),它可以由两种类型的数组成

  • 类型1:2的整数次幂
  • 类型2:k的阶乘

这个数可以由这两种类型任意多个组成,但是组成n的数字中不能由相同数字。

问最少由多少个这两种类型的数组成整数n

2思路

这是一个整数划分问题,但是这个整数特别大,所以不能用动态规划来求。

我们可以假设只有类型1组成整数n,那么只需要n的2进制有多少个1就是答案了。

但是我们现在是两种类型的结合

假设有k个数的阶乘和为sum之后,那么就剩下n-sum了,剩下全部由类型1组成。

所以 n = k + n-k ,cnt = k + get_bit_count(n-sum)

所以为了使cnt最小,我们只需要计算所有k的可能性即可,这里k最多有14,因为15!> 1e12 了。所以我们可以用位运算来枚举所有的集合,而且集合中每个数字都不一样,还有n-sum中的所有数也不会一样。

注意这里使没办法贪心的,没有规律可言,所以只能按照枚举所以的情况即可。

3代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> PII;
#define x first
#define y second
const int N = 2e4 + 10;
PII a[N];
ll f[20];
int get_bit(ll x)
{
    int ans = 0;
    for (int i = 0; i < 60; i++)
    {
        if (x >> i & 1)
            ans++;
    }
    return ans;
}
void init()
{
    f[0] = 1;
    for (int i = 1; i <= 14; i++)
        f[i] = f[i - 1] * i;
    for (int i = 0; i < 1 << 14; i++)
    {
        ll ans = 0;
        int cnt = 0;
        for (int j = 0; j < 14; j++)
        {
            if (i >> j & 1)
            {
                ans += f[j + 1];
                cnt++;
            }
        }
        a[i] = {ans, cnt};
    }
}
void solve()
{
    ll n;
    cin >> n;
    int ans = 1e9;
    for (int i = 0; i < 1 << 14; i++)
    {
        if (a[i].x <= n)
        {
            ans = min(ans, a[i].y + get_bit(n - a[i].x));
        }
    }
    cout << ans << endl;
    return;
}
signed main()
{
    // freopen("in.in", "r", stdin);
    // freopen("out.out", "w", stdout);
    init();
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}
相关文章
|
8月前
计算思维学习总结(一)
计算思维学习总结(一)
71 0
带你读《计算思维导论实验 与习题指导》之一:初识计算思维
本书围绕《计算思维导论》主教材,设计了13个实验,并针对前8章内容设计了习题,包括单选题、多选题、填空题、判断题等。通过实验和习题,能帮助学生:了解计算思维的概念和计算机发展简史;理解进制转换、字符编码和中文编码等相关知识,掌握数制转换的方法和口诀;了解计算机硬件并学会配置与组装计算机,同时能够对简单故障进行判断和排除;掌握上网浏览、查询资料、收发电子邮件等信息时代的必备知识,同时学会局域网的搭建、WWW和FTP服务器的构建;掌握利用Access创建数据库的方法,并能初步设计与管理数据库;掌握命题符号化方法,以及基本的推理理论,并能利用真值表、等值演算等方法进行简单的逻辑推理等能力。
|
监控 架构师 程序员
第八章 思维模型
第八章 思维模型
139 0
编写s=1+2+3+...+n思路打破认知
最近在和领导讨论架构设计,其中涉及到如何通过代码来体现面向对象?通过一个例子来打破了原有的认知,以此总结记录自己的提升和成长
|
机器学习/深度学习 人工智能 自然语言处理
扩散模型背后数学太难了,啃不动?谷歌用统一视角讲明白了
扩散模型背后数学太难了,啃不动?谷歌用统一视角讲明白了
256 0
|
算法 搜索推荐
《十大排序算法》让你的思维流动起来。今天的主角又是排序思想你了解多少。每种算法的内容在代码中体现出来。
《十大排序算法》让你的思维流动起来。今天的主角又是排序思想你了解多少。每种算法的内容在代码中体现出来。
202 0
《十大排序算法》让你的思维流动起来。今天的主角又是排序思想你了解多少。每种算法的内容在代码中体现出来。
算法竞赛之查找算法(持续补充...)
算法竞赛之查找算法(持续补充...)
|
人工智能 算法 安全
8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法
对于程序员来说,提高自己的编程能力,算是给自己定的职业发展目标之一,不过定一个成为编程大神的目标很容易,具体做起来可能就不是一件简单的事了。首先,既然决定“我要变得更好”,得先知道“更好”是什么样子的。另外,不能“想变得更好”,却没有任何具体可行的措施。
964 2
8种提升程序猿编程能力的方法+编程思维四个核心:分解、抽象、模式识别和算法