整数拆分

整数拆分

我们规定 f(x)x2)表示整数 x 的除本身之外的最大因数。

例如,f(6)=3f(25)=5f(2)=1

现在,给定一个整数 n,请你将其拆分为 kn1,n2,,nk(也可以不拆分,即 k=1),要求:

  • n1+n2++nk=n
  • 对于 1ikni2 始终成立。
  • f(n1)+f(n2)++f(nk) 的值应尽可能小。

输出 f(n1)+f(n2)++f(nk) 的最小可能值。

输入格式

一个整数 n

输出格式

一个整数,表示 f(n1)+f(n2)++f(nk) 的最小可能值。

数据范围

4 个测试点满足 2n30
所有测试点满足 2n2×109

输入样例1:

4

输出样例1:

2

输入样例2:

27

输出样例2:

3

 

解题思路

  如果n是质素那么有f(n)=1

  如果n是偶数,根据哥德巴赫猜想:“每一个不小于6的偶数都是两个奇素数之和”。

  • 如果n=2,因为2是质数所以有f(2)=1
  • 如果n=4,如果不拆分的话f(4)=2,如果拆分的话则拆成两个2f(2)+f(2)=2。因此有f(4)=2
  • 如果n是大于等于6的偶数,因为n是偶数因此必然不是质数,因此必然有f(n)2。又根据哥德巴赫猜想,每一个不小于6的偶数都是两个奇素数之和,而每个质数的f均是1,因此可以取到2,即如果n是大于等于6的偶数则有f(n)=2

  如果n既不是质数,也不是偶数,那么n是奇合数,因此f(n)2。如果要取到2,意味着可以拆除两个质数的和,又因为n是奇数,因此这两个数必然有一个是奇数,另外一个是偶数,且两个数都要是偶数,因此偶数必然取2

  • 如果n2是质数,那么答案就是2
  • 如果n2是合数,那么f(n)3。如果n要拆成3个以上的数的和,那么f(n)3,因为即使是3个质数答案也是要大于等于3。现在不管是拆成两个数还是三个数以上,答案都是大于等于3。根据哥德巴赫猜想,每一个不小于9的奇数都是三个奇素数之和,因此3是可以取到的。因此如果n2是合数,那么f(n)=3357已经在判断质数的时候被处理了)。

  AC代码如下:

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 bool is_prime(int x) {
 5     for (int i = 2; i <= x / i; i++) {
 6         if (x % i == 0) return false;
 7     }
 8     return true;
 9 }
10 
11 int main() {
12     int n;
13     cin >> n;
14     if (is_prime(n)) printf("1");
15     else if (n % 2 == 0 || is_prime(n - 2)) printf("2");
16     else printf("3");
17     
18     return 0;
19 }
复制代码

 

参考资料

  AcWing 4622. 整数拆分(AcWing杯 - 周赛):https://www.acwing.com/video/4446/

  哥德巴赫猜想:https://hanyu.baidu.com/s?wd=%E5%93%A5%E5%BE%B7%E5%B7%B4%E8%B5%AB%E7%8C%9C%E6%83%B3&device=pc&from=home

posted @   onlyblues  阅读(71)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示