【洛谷】P1028 [NOIP2001 普及组] 数的计算

分手后的思念是犯贱 2022-09-07 01:20 352阅读 0赞

题目

题目链接
题目要读两遍才能理解讲什么,主要意思就是让你找出一个数可以被分裂形成多少个数?分裂的规则是,不能比该数最左侧的数的一半儿大。

思想

主要考察递归+记忆化搜索 ,下面以数字6为示例,给出推理过程:

在这里插入图片描述
加上自己原本的数,那么最后的结果就是可以得到6个数。接着我们来看下数字12可以被分成多少个数?

在这里插入图片描述

可以很明显的看到,我们需要用到一个记忆化搜索的技巧,这样记录已经遍历过的数,就不用再重复递归搜索了,会大大的节约时间。

代码

  1. #include<iostream>
  2. using namespace std;
  3. int res = 0;
  4. const int maxN = 1005;
  5. //使用记忆化搜索,否则会TLE
  6. int record[maxN]; //记录每个数字可以拆分的个数
  7. //返回数字num可以得到的个数
  8. void get_num(int num){
  9. if (num == 1) //边界条件
  10. return ; // 最后这一种
  11. if (record[num]!= -1){
  12. res += record[num];
  13. return ; //直接加完返回
  14. }
  15. int start = res;
  16. for (int i = 1;i<= num/2;i++){ //递归循环
  17. res ++;
  18. get_num(i);
  19. }
  20. record[num] = res- start;//记录这个数可以的次数
  21. }
  22. int main(){
  23. int n;
  24. cin >> n;
  25. fill(record,record+maxN,-1);
  26. get_num(n);
  27. cout << res + 1 <<"\n";
  28. }

发表评论

表情:
评论列表 (有 0 条评论,352人围观)

还没有评论,来说两句吧...

相关阅读

    相关 P1028 计算

    嗯... 首先这道题想到的就是递推.... 但是递推失败 (不知道自己是怎么想的 然后又想打一个暴力,但是数的最高位太难存储了,所以又放弃了(并且好