Factorials and Powers of Two

Factorials and Powers of Two

分析:我们可以看出这道题目的描述并不是很复杂,就是说对于一个给定的整数n,我们能否把他拆成k个powerful的数,也就是说这k个数要么是2的幂次,要么是某个数的阶乘,并且我们要让当前的k越小越好;然后如果不能被拆的话输出-1;

我们这样来看,先看会不会输出-1,我们如果把这个整数n用二进制的方法写出来,每个1都表明可以写成某个powerful的数,所以不可能输出-1;

那么我们就可以发现了k的个数就是这里二进制表示中1的个数,但是我们考虑到还有阶乘,我们令阶乘的和为s,个数为cnt,则k = cnt + F(n-s),这里的F函数就是根据二进制找1;

既然这样我们就可以枚举每个阶乘的可能性,我们发现14!已经是最大的可能了,因为15!就已经超过了1^12的数据范围,并且我们可以发现1!和2!是不需要考虑的,因为他们和幂次是一换一的关系没有必要,所以最多只需要枚举2^12次,找到最小值即可!

那么这里的关键是在于我怎么把这么多种可能枚举出来呢,很显然不适合用dfs,所以我们这里枚举i为0~1<

代码:

  1. include

  2. define INF 1100000000

  3. using namespace std ;
  4. typedef long long LL ;
  5. typedef pair PII ;
  6. LL fa [20 ],n ;
  7. int k =INF ;
  8. int find (LL x ){
  9. int cnt =0 ;
  10. while (x ){
  11. cnt +=x &1 ;
  12. x >>=1 ;
  13. }
  14. return cnt ;
  15. }
  16. int main ()
  17. {
  18. int t ;
  19. cin >>t ;
  20. fa [1 ]=1 ;
  21. fa [2 ]=2 ;
  22. for (int i =3 ;i
  23. while (t –){
  24. k =1100000000 ;
  25. cin >>n ;
  26. for (int i =0 ;i
  27. int cnt =0 ;
  28. LL s =0 ;
  29. for (int j =0 ;j
  30. if (i &(1 <<j )){
  31. cnt ++;
  32. s +=fa [j +3 ];
  33. }
  34. }
  35. if (s >n )continue ;
  36. k =min (k ,cnt +find (n -s ));
  37. }
  38. cout <<k <<‘\n’;
  39. }
  40. return 0 ;
  41. }

Original: https://www.cnblogs.com/ZheyuHarry/p/16102176.html
Author: ZheyuHarry
Title: Factorials and Powers of Two

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/583604/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球