• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
scorpiorax
博客园    首页    新随笔    联系   管理    订阅  订阅
LOJ10155数字转换

题目描述

如果一个数 x 的约数和 y (不包括他本身)比他本身小,那么 x 可以变成 y,y 也可以变成 x。例如 4 可以变为 3,1 可以变为 7。限定所有数字变换在不超过 n 的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。

输入格式

输入一个正整数 n。

输出格式

输出不断进行数字变换且不出现重复数字的最多变换步数。

样例

样例输入

7

样例输出

3

样例说明

一种方案为 4→3→1→7。

数据范围与提示

对于 100% 的数据,1≤n≤50000。

 

******求树的最长链问题,先预处理每个数的约数,将可以互相转化的数之间连边,很明显这是一颗树,我们要求树的最长路径。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int sum[50005] = {0},n,d1[50005],d2[50005];
 7 void ready()
 8 {
 9     int i,j;
10     scanf("%d",&n);
11     for(i = 1;i <= n;i++)
12     {
13         for(j = 2;j <= n / i;j++)
14         {
15             if(i * j > n)
16             break;
17             sum[i * j] += i;
18         }
19     }
20 }
21 void dp()
22 {
23     int i;
24     for(i = n;i >= 1;i--) //因为大数字一定是小数字的后代 
25     {
26         if(sum[i] < i) //sum[i]是i的父亲节点 
27         {
28             if(d1[i] + 1 > d1[sum[i]])//修改sum[i]这点的最大值 
29             {
30                 d2[sum[i]] = d1[sum[i]];
31                 d1[sum[i]] = d1[i] + 1;
32             }
33             else if(d1[i] + 1 >d2[sum[i]])
34             {
35                 d2[sum[i]] = d1[i] + 1;
36             }
37         }
38     }
39 }
40 int main()
41 {
42     int i,ans = 0;
43     ready();
44     dp(); 
45     for(i = 1;i <= n;i++) //遍历所有的节点,找最大值+次大值的最大值 
46     {
47         if(d1[i] + d2[i] > ans)
48         ans = d1[i] + d2[i];
49     } 
50     printf("%d",ans);
51     return 0;
52 }

 

 

posted on 2018-11-06 14:24  scorpiorax  阅读(710)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3